]> granicus.if.org Git - clang/commitdiff
Fix <rdar://problem/6786597> varargs not supported for Blocks under clang.
authorSteve Naroff <snaroff@apple.com>
Wed, 15 Apr 2009 19:33:47 +0000 (19:33 +0000)
committerSteve Naroff <snaroff@apple.com>
Wed, 15 Apr 2009 19:33:47 +0000 (19:33 +0000)
Teach Sema::SemaBuiltinVAStart() about blocks.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69201 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/variadic-block.c [new file with mode: 0644]

index d2aec65cef20da8efc070a118d44a99eb836601c..827f63cfcd4fe5eec603051e322c84e2eda4f950 100644 (file)
@@ -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<FunctionProtoType>(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 (file)
index 0000000..29f597b
--- /dev/null
@@ -0,0 +1,41 @@
+// RUN: clang-cc %s -verify -fsyntax-only -fblocks
+
+#include <stdarg.h>
+
+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;
+}
+