]> granicus.if.org Git - clang/commitdiff
Check that the return/argument types of calls are complete.
authorEli Friedman <eli.friedman@gmail.com>
Sun, 22 Mar 2009 22:00:50 +0000 (22:00 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sun, 22 Mar 2009 22:00:50 +0000 (22:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67485 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.def
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/SemaCXX/enum.cpp

index 819a456c5bd4a72e7a2fbabea0e1a9d0179d9c03..f2c0994f3a17f90489bed3a749770e2b892cf78b 100644 (file)
@@ -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,
index 945ab5986f943fe6ae79b47901a4c2fafcc5afd1..390554ff9e14f51cdc5120fa245fa1ba931aed27 100644 (file)
@@ -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<
index 5539df40034d9841f6013e4e7b78621ffdc417ac..079ff74d79590532852b079f63b2b378b9758ff2 100644 (file)
@@ -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);
     }
   }
index 156dfd62088462068ad8f224a4d8597547e689f3..9657113429387227a7356cbb995f74bdcc82fee8 100644 (file)
@@ -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}}