diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 1536c950d199..d63a57a14ce7 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/Sema/SemaExpr.cpp @@ -367,10 +367,22 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc, QualType qType = UsualUnaryConversions(funcExpr->getType()); assert(!qType.isNull() && "no type for function call expression"); - const PointerType *PT = dyn_cast(qType.getCanonicalType()); + // C99 6.5.2.2p1 - "The expression that denotes the called function shall have + // type pointer to function". + const PointerType *PT = dyn_cast(qType); + if (PT == 0) PT = dyn_cast(qType.getCanonicalType()); + + if (PT == 0) + return Diag(funcExpr->getLocStart(), diag::err_typecheck_call_not_function, + SourceRange(funcExpr->getLocStart(), RParenLoc)); const FunctionType *funcT = dyn_cast(PT->getPointeeType()); - assert(funcT && "ParseCallExpr(): not a function type"); + if (funcT == 0) + funcT = dyn_cast(PT->getPointeeType().getCanonicalType()); + + if (funcT == 0) + return Diag(funcExpr->getLocStart(), diag::err_typecheck_call_not_function, + SourceRange(funcExpr->getLocStart(), RParenLoc)); // If a prototype isn't declared, the parser implicitly defines a func decl QualType resultType = funcT->getResultType(); diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 652678a9dc59..1245a671b196 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -590,6 +590,8 @@ DIAG(err_typecheck_expression_not_modifiable_lvalue, ERROR, "expression is not assignable") DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, ERROR, "incomplete type '%0' is not assignable") +DIAG(err_typecheck_call_not_function, ERROR, + "called object is not a function or function pointer") DIAG(err_typecheck_call_too_few_args, ERROR, "too few arguments to function") DIAG(err_typecheck_call_too_many_args, ERROR,