diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -46,6 +46,7 @@ #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/SaveAndRestore.h" using namespace clang; @@ -6433,6 +6434,17 @@ checkDirectCallValidity(*this, Fn, FD, ArgExprs); } + if (getLangOpts().CDependence && + (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."); + return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy, + VK_RValue, RParenLoc); + } + return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc, ExecConfig, IsExecConfig); } @@ -6572,7 +6584,7 @@ RParenLoc, NumParams, UsesADL); } - if (!getLangOpts().CPlusPlus) { + if (!getLangOpts().CPlusPlus && !getLangOpts().CDependence) { // Forget about the nulled arguments since typo correction // do not handle them well. TheCall->shrinkNumArgs(Args.size()); diff --git a/clang/test/AST/ast-dump-recovery.c b/clang/test/AST/ast-dump-recovery.c --- a/clang/test/AST/ast-dump-recovery.c +++ b/clang/test/AST/ast-dump-recovery.c @@ -55,3 +55,18 @@ // CHECK-NEXT: `-DeclRefExpr {{.*}} 'some_func' compoundOp += some_func(); } + +void test3() { + // CHECK: CallExpr {{.*}} '' 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(); + // FIXME: the broken AST will be preserved once we remove the early typo correction + // in Sema::CheckPlaceholderExpr. + // CHECK-NOT: DeclRefExpr {{.*}} 'ext' 'int (int)' + ext(undef_var); +} diff --git a/clang/test/Sema/error-dependence.c b/clang/test/Sema/error-dependence.c --- a/clang/test/Sema/error-dependence.c +++ b/clang/test/Sema/error-dependence.c @@ -6,4 +6,8 @@ // verify "assigning to 'int' from incompatible type ''" is // not emitted. s = call(); // expected-error {{too few arguments to function call}} + + // verify disgnostic "called object type '' is not a function + // or function pointer" is not emitted. + (*__builtin_classify_type)(1); // expected-error {{builtin functions must be directly called}} }