From: Eli Friedman Date: Sun, 22 Mar 2009 22:00:50 +0000 (+0000) Subject: Check that the return/argument types of calls are complete. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e7c6f7aa7e8ee1f0acacc314dcf59d5dadff1524;p=clang Check that the return/argument types of calls are complete. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67485 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index 819a456c5b..f2c0994f3a 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -1174,6 +1174,10 @@ DIAG(err_block_decl_ref_not_modifiable_lvalue, ERROR, "variable is not assignable (missing __block type specifier)") DIAG(err_typecheck_call_not_function, ERROR, "called object type %0 is not a function or function pointer") +DIAG(err_call_incomplete_return, ERROR, + "return type of called function (%0) is incomplete") +DIAG(err_call_incomplete_argument, ERROR, + "argument type %0 is incomplete") DIAG(err_typecheck_call_too_few_args, ERROR, "too few arguments to %select{function|block|method}0 call") DIAG(err_typecheck_call_too_many_args, ERROR, diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 945ab5986f..390554ff9e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1118,6 +1118,10 @@ def err_block_decl_ref_not_modifiable_lvalue : Error< "variable is not assignable (missing __block type specifier)">; def err_typecheck_call_not_function : Error< "called object type %0 is not a function or function pointer">; +def err_call_incomplete_return : Error< + "return type of called function (%0) is incomplete">; +def err_call_incomplete_argument : Error< + "argument type %0 is incomplete">; def err_typecheck_call_too_few_args : Error< "too few arguments to %select{function|block|method}0 call">; def err_typecheck_call_too_many_args : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5539df4003..079ff74d79 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2161,6 +2161,12 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, if (i < NumArgs) { Arg = Args[i]; + if (RequireCompleteType(Arg->getSourceRange().getBegin(), + ProtoArgType, + diag::err_call_incomplete_argument, + Arg->getSourceRange())) + return true; + // Pass the argument. if (PerformCopyInitialization(Arg, ProtoArgType, "passing")) return true; @@ -2331,6 +2337,14 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) << Fn->getType() << Fn->getSourceRange()); + // Check for a valid return type + if (!FuncT->getResultType()->isVoidType() && + RequireCompleteType(Fn->getSourceRange().getBegin(), + FuncT->getResultType(), + diag::err_call_incomplete_return, + TheCall->getSourceRange())) + return ExprError(); + // We know the result type of the call, set it. TheCall->setType(FuncT->getResultType().getNonReferenceType()); @@ -2345,6 +2359,11 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, for (unsigned i = 0; i != NumArgs; i++) { Expr *Arg = Args[i]; DefaultArgumentPromotion(Arg); + if (RequireCompleteType(Arg->getSourceRange().getBegin(), + Arg->getType(), + diag::err_call_incomplete_argument, + Arg->getSourceRange())) + return ExprError(); TheCall->setArg(i, Arg); } } diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp index 156dfd6208..9657113429 100644 --- a/test/SemaCXX/enum.cpp +++ b/test/SemaCXX/enum.cpp @@ -26,13 +26,13 @@ void bar() { /// PR3688 struct s1 { - enum e1 (*bar)(void); // expected-error{{ISO C++ forbids forward references to 'enum' types}} + enum e1 (*bar)(void); // expected-error{{ISO C++ forbids forward references to 'enum' types}} expected-note{{forward declaration of 'enum s1::e1'}} }; enum e1 { YES, NO }; static enum e1 badfunc(struct s1 *q) { - return q->bar(); // expected-error{{incompatible type returning 'enum s1::e1', expected 'enum e1'}} + return q->bar(); // expected-error{{return type of called function ('enum s1::e1') is incomplete}} } enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}}