[AST][RecoveryExpr] Support dependent cast-expr in C for error-recovery.

Suppress spurious "typecheck_cond_expect_scalar_operand" diagnostic.

See whole context: https://reviews.llvm.org/D85025

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D84387
This commit is contained in:
Haojian Wu 2020-10-08 10:00:29 +02:00
parent ba268d2fb0
commit a96bcfb196
3 changed files with 21 additions and 1 deletions

View File

@ -2707,6 +2707,17 @@ void CastOperation::CheckCStyleCast() {
return;
}
// If the type is dependent, we won't do any other semantic analysis now.
if (Self.getASTContext().isDependenceAllowed() &&
(DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||
SrcExpr.get()->isValueDependent())) {
assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||
SrcExpr.get()->containsErrors()) &&
"should only occur in error-recovery path.");
assert(Kind == CK_Dependent);
return;
}
// Overloads are allowed with C extensions, so we need to support them.
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
DeclAccessPair DAP;

View File

@ -81,4 +81,9 @@ void test2() {
// CHECK-NEXT: |-DeclRefExpr {{.*}} 'int *' lvalue
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'float' lvalue
(ptr > f ? ptr : f);
// CHECK: CStyleCastExpr {{.*}} 'float' contains-errors <Dependent>
// CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func'
(float)some_func();
}

View File

@ -1,11 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -verify -frecovery-ast -fno-recovery-ast-type %s
int call(int); // expected-note2 {{'call' declared here}}
int call(int); // expected-note3 {{'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}}
// 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}}
}
void test2(int* ptr, float f) {