[clang] 334ec6f - [AST][RecoveryExpr] Support dependent conditional operators in C for error recovery.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 7 00:34:29 PDT 2020


Author: Haojian Wu
Date: 2020-10-07T09:33:57+02:00
New Revision: 334ec6f807fa65e09571fa42a0c3be0eb39e7c0f

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

LOG: [AST][RecoveryExpr] Support dependent conditional operators in C for error recovery.

suppress spurious "typecheck_cond_expect_scalar" diagnostic.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D84322

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 ee41d5f5b37d..17bb82af975f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8067,6 +8067,16 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
   VK = VK_RValue;
   OK = OK_Ordinary;
 
+  if (Context.isDependenceAllowed() &&
+      (Cond.get()->isTypeDependent() || LHS.get()->isTypeDependent() ||
+       RHS.get()->isTypeDependent())) {
+    assert(!getLangOpts().CPlusPlus);
+    assert(Cond.get()->containsErrors() || LHS.get()->containsErrors() ||
+           RHS.get()->containsErrors() &&
+               "should only occur in error-recovery path.");
+    return Context.DependentTy;
+  }
+
   // The OpenCL operator with a vector condition is sufficiently
   // 
diff erent to merit its own checker.
   if ((getLangOpts().OpenCL && Cond.get()->getType()->isVectorType()) ||

diff  --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c
index 66830e072a2a..7b2bcf27ecce 100644
--- a/clang/test/AST/ast-dump-recovery.c
+++ b/clang/test/AST/ast-dump-recovery.c
@@ -71,4 +71,14 @@ void test2() {
   // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'some_func'
   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
   some_func(), 1;
+
+  // conditional operator (comparison is invalid)
+  float f;
+  // CHECK:     ConditionalOperator {{.*}} '<dependent type>' contains-errors
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
+  // CHECK-NEXT: | |-DeclRefExpr {{.*}} 'int *' lvalue
+  // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'float' lvalue
+  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'int *' lvalue
+  // CHECK-NEXT: `-DeclRefExpr {{.*}} 'float' lvalue
+  (ptr > f ? ptr : f);
 }

diff  --git a/clang/test/Sema/error-dependence.c b/clang/test/Sema/error-dependence.c
index a98b021094de..b83a79f8c4c6 100644
--- a/clang/test/Sema/error-dependence.c
+++ b/clang/test/Sema/error-dependence.c
@@ -1,9 +1,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -frecovery-ast -fno-recovery-ast-type %s
 
-int call(int); // expected-note {{'call' declared here}}
+int call(int); // expected-note2 {{'call' declared here}}
 
 void test1(int s) {
   // verify "assigning to 'int' from incompatible type '<dependent type>'" is
   // not emitted.
   s = call(); // expected-error {{too few arguments to function call}}
 }
+
+void test2(int* ptr, float f) {
+  // verify diagnostic "used type '<dependent type>' where arithmetic or pointer
+  // type is required" is not emitted.
+  (call() ? ptr : f); // expected-error {{too few arguments to function call}}
+}


        


More information about the cfe-commits mailing list