[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
This commit is contained in:
Haojian Wu 2020-10-07 09:33:57 +02:00
parent 53b3873cf4
commit 334ec6f807
3 changed files with 27 additions and 1 deletions

View File

@ -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
// different to merit its own checker.
if ((getLangOpts().OpenCL && Cond.get()->getType()->isVectorType()) ||

View File

@ -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);
}

View File

@ -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}}
}