From bb2b3be9e1b3ae66b2f48e9bc78aa22621525361 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 15 Dec 2008 22:05:35 +0000 Subject: [PATCH] Make error handling for va_start a bit more robust. Fixes PR3213. llvm-svn: 61055 --- clang/lib/Sema/SemaChecking.cpp | 19 ++++++++++++++----- clang/test/Sema/varargs.c | 9 +++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 0c7da0edb05d..14aa99682134 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -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(getCurFunctionDecl()->getType())->isVariadic(); - else + if (getCurFunctionDecl()) { + if (FunctionTypeProto* FTP = + dyn_cast(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); diff --git a/clang/test/Sema/varargs.c b/clang/test/Sema/varargs.c index efde2f0a7cb5..5e0f28b7c25c 100644 --- a/clang/test/Sema/varargs.c +++ b/clang/test/Sema/varargs.c @@ -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}} +}