forked from OSchip/llvm-project
[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
This commit is contained in:
parent
25e437ec1e
commit
bb406f36dc
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue