From bb406f36dca3d53690a31e051d6f75f11eba6aa1 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 12 Oct 2020 11:12:58 +0200 Subject: [PATCH] [AST][RecoveryExpr] Build dependent callexpr in C for error-recovery. See whole context: https://reviews.llvm.org/D85025 Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D84304 --- clang/lib/Sema/SemaExpr.cpp | 19 +++++++++++++++++-- clang/test/AST/ast-dump-recovery.c | 15 +++++++++++++++ clang/test/Sema/error-dependence.c | 3 +++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 68a8777eae73..b5a366bc7175 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6375,6 +6375,21 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, checkDirectCallValidity(*this, Fn, FD, ArgExprs); } + if (Context.isDependenceAllowed() && + (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs))) { + assert(!getLangOpts().CPlusPlus); + assert(Fn->containsErrors() || + llvm::any_of(ArgExprs, + [](clang::Expr *E) { return E->containsErrors(); }) && + "should only occur in error-recovery path."); + QualType ReturnType = + llvm::isa_and_nonnull(NDecl) + ? dyn_cast(NDecl)->getCallResultType() + : Context.DependentTy; + return CallExpr::Create(Context, Fn, ArgExprs, ReturnType, + Expr::getValueKindForType(ReturnType), RParenLoc, + CurFPFeatureOverrides()); + } return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc, ExecConfig, IsExecConfig); } @@ -6515,7 +6530,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, CurFPFeatureOverrides(), NumParams, UsesADL); } - if (!getLangOpts().CPlusPlus) { + if (!Context.isDependenceAllowed()) { // Forget about the nulled arguments since typo correction // do not handle them well. TheCall->shrinkNumArgs(Args.size()); @@ -19052,7 +19067,7 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { /// Check for operands with placeholder types and complain if found. /// Returns ExprError() if there was an error and no recovery was possible. ExprResult Sema::CheckPlaceholderExpr(Expr *E) { - if (!getLangOpts().CPlusPlus) { + if (!Context.isDependenceAllowed()) { // C cannot handle TypoExpr nodes on either side of a binop because it // doesn't handle dependent types properly, so make sure any TypoExprs have // been dealt with before checking the operands. diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c index d14aedebe490..4cb0c5be21e0 100644 --- a/clang/test/AST/ast-dump-recovery.c +++ b/clang/test/AST/ast-dump-recovery.c @@ -87,3 +87,18 @@ void test2() { // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func' (float)some_func(); } + +void test3() { + // CHECK: CallExpr {{.*}} '' contains-errors + // CHECK-NEXT: |-ParenExpr {{.*}} contains-errors lvalue + // CHECK-NEXT: | `-RecoveryExpr {{.*}} contains-errors + // CHECK-NEXT: | `-DeclRefExpr {{.*}} '__builtin_classify_type' + // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 + (*__builtin_classify_type)(1); + + extern void ext(); + // CHECK: CallExpr {{.*}} 'void' contains-errors + // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ext' + // CHECK-NEXT: `-RecoveryExpr {{.*}} '' + ext(undef_var); +} diff --git a/clang/test/Sema/error-dependence.c b/clang/test/Sema/error-dependence.c index 41733cdba3fe..608e9af4444e 100644 --- a/clang/test/Sema/error-dependence.c +++ b/clang/test/Sema/error-dependence.c @@ -10,6 +10,9 @@ void test1(int s) { // verify diagnostic "operand of type '' where arithmetic or // pointer type is required" is not emitted. (float)call(); // expected-error {{too few arguments to function call}} + // verify disgnostic "called object type '' is not a function + // or function pointer" is not emitted. + (*__builtin_classify_type)(1); // expected-error {{builtin functions must be directly called}} } void test2(int* ptr, float f) {