[clang] bb406f3 - [AST][RecoveryExpr] Build dependent callexpr in C for error-recovery.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 12 02:18:36 PDT 2020


Author: Haojian Wu
Date: 2020-10-12T11:15:01+02:00
New Revision: bb406f36dca3d53690a31e051d6f75f11eba6aa1

URL: https://github.com/llvm/llvm-project/commit/bb406f36dca3d53690a31e051d6f75f11eba6aa1
DIFF: https://github.com/llvm/llvm-project/commit/bb406f36dca3d53690a31e051d6f75f11eba6aa1.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/Sema/SemaExpr.cpp
    clang/test/AST/ast-dump-recovery.c
    clang/test/Sema/error-dependence.c

Removed: 
    


################################################################################
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<FunctionDecl>(NDecl)
+            ? dyn_cast<FunctionDecl>(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 {{.*}} '<dependent type>' 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 {{.*}} '<dependent type>'
+  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 '<dependent 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 '<dependent 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) {


        


More information about the cfe-commits mailing list