From: Steve Naroff Date: Wed, 15 Apr 2009 19:33:47 +0000 (+0000) Subject: Fix varargs not supported for Blocks under clang. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd9c51433c06705645d1ee5a13da3c9a72d7d025;p=clang Fix varargs not supported for Blocks under clang. Teach Sema::SemaBuiltinVAStart() about blocks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69201 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d2aec65cef..827f63cfcd 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -209,7 +209,9 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { // Determine whether the current function is variadic or not. bool isVariadic; - if (getCurFunctionDecl()) { + if (CurBlock) + isVariadic = CurBlock->isVariadic; + else if (getCurFunctionDecl()) { if (FunctionProtoType* FTP = dyn_cast(getCurFunctionDecl()->getType())) isVariadic = FTP->isVariadic(); @@ -234,7 +236,9 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { // FIXME: This isn't correct for methods (results in bogus warning). // Get the last formal in the current function. const ParmVarDecl *LastArg; - if (FunctionDecl *FD = getCurFunctionDecl()) + if (CurBlock) + LastArg = *(CurBlock->TheDecl->param_end()-1); + else if (FunctionDecl *FD = getCurFunctionDecl()) LastArg = *(FD->param_end()-1); else LastArg = *(getCurMethodDecl()->param_end()-1); diff --git a/test/Sema/variadic-block.c b/test/Sema/variadic-block.c new file mode 100644 index 0000000000..29f597b006 --- /dev/null +++ b/test/Sema/variadic-block.c @@ -0,0 +1,41 @@ +// RUN: clang-cc %s -verify -fsyntax-only -fblocks + +#include + +int main(int argc, char *argv[]) { + + long (^addthem)(const char *, ...) = ^long (const char *format, ...){ + va_list argp; + const char *p; + int i; + char c; + double d; + long result = 0; + va_start(argp, format); + for (p = format; *p; p++) switch (*p) { + case 'i': + i = va_arg(argp, int); + result += i; + break; + case 'd': + d = va_arg(argp, double); + result += (int)d; + break; + case 'c': + c = va_arg(argp, int); + result += c; + break; + } + return result; + }; + long testresult = addthem("ii", 10, 20); + if (testresult != 30) { + return 1; + } + testresult = addthem("idc", 30, 40.0, 'a'); + if (testresult != (70+'a')) { + return 1; + } + return 0; +} +