aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-03-22 22:00:50 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-03-22 22:00:50 +0000
commite7c6f7aa7e8ee1f0acacc314dcf59d5dadff1524 (patch)
tree8712a1816d8549c5f04a9ad2e136635bb8b8a3cc
parentb808c952bbff821dce727dd801a1098d64394f98 (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.def4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--lib/Sema/SemaExpr.cpp19
-rw-r--r--test/SemaCXX/enum.cpp4
4 files changed, 29 insertions, 2 deletions
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}}