]> granicus.if.org Git - clang/commitdiff
Make error handling for va_start a bit more robust. Fixes PR3213.
authorEli Friedman <eli.friedman@gmail.com>
Mon, 15 Dec 2008 22:05:35 +0000 (22:05 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 15 Dec 2008 22:05:35 +0000 (22:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61055 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/varargs.c

index 0c7da0edb05df3750042d2a3bbb114e0dc351495..14aa99682134d7677f51139e0a91e89204c8596e 100644 (file)
@@ -160,14 +160,23 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) {
                      (*(TheCall->arg_end()-1))->getLocEnd());
     return true;
   }
-  
+
+  if (TheCall->getNumArgs() < 2) {
+    return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
+      << 0 /*function call*/;
+  }
+
   // Determine whether the current function is variadic or not.
   bool isVariadic;
-  if (getCurFunctionDecl())
-    isVariadic =
-      cast<FunctionTypeProto>(getCurFunctionDecl()->getType())->isVariadic();
-  else
+  if (getCurFunctionDecl()) {
+    if (FunctionTypeProto* FTP =
+            dyn_cast<FunctionTypeProto>(getCurFunctionDecl()->getType()))
+      isVariadic = FTP->isVariadic();
+    else
+      isVariadic = false;
+  } else {
     isVariadic = getCurMethodDecl()->isVariadic();
+  }
   
   if (!isVariadic) {
     Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function);
index efde2f0a7cb5f2a4cd1f83de13a87c44c134acb7..5e0f28b7c25c16aab92363a802c0c636f44589ca 100644 (file)
@@ -34,3 +34,12 @@ void f4(const char *msg, ...) {
  __builtin_va_end (ap);
 }
 
+void f5() {
+  __builtin_va_list ap;
+  __builtin_va_start(ap,ap); // expected-error {{'va_start' used in function with fixed args}}
+}
+
+void f6(int a, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap); // expected-error {{too few arguments to function}}
+}