]> granicus.if.org Git - clang/commitdiff
Declaring local static in global block
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 30 Nov 2010 23:07:14 +0000 (23:07 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 30 Nov 2010 23:07:14 +0000 (23:07 +0000)
literal declaration caused crash in CodeGen.
This patch fixes it. pr8707

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

lib/CodeGen/CGDecl.cpp
test/CodeGen/blockwithlocalstatic.c [new file with mode: 0644]

index 1a129e753687402341279dbe5d20aada32e85f7e..7aeacafce4483ed01749111f5ada981d96752095 100644 (file)
@@ -145,14 +145,24 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
   }
   
   std::string ContextName;
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
+  if (!CGF.CurFuncDecl) {
+    // Better be in a block declared in global scope.
+    const NamedDecl *ND = cast<NamedDecl>(&D);
+    const DeclContext *DC = ND->getDeclContext();
+    if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
+      MangleBuffer Name;
+      CGM.getMangledName(GlobalDecl(), Name, BD);
+      ContextName = Name.getString();
+    }
+    else
+      assert(0 && "Unknown context for block static var decl");
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
     llvm::StringRef Name = CGM.getMangledName(FD);
     ContextName = Name.str();
   } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
     ContextName = CGF.CurFn->getName();
   else
-    // FIXME: What about in a block??
-    assert(0 && "Unknown context for block var decl");
+    assert(0 && "Unknown context for static var decl");
   
   return ContextName + Separator + D.getNameAsString();
 }
diff --git a/test/CodeGen/blockwithlocalstatic.c b/test/CodeGen/blockwithlocalstatic.c
new file mode 100644 (file)
index 0000000..1fdaaf3
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -emit-llvm -o - %s | FileCheck %s
+// pr8707
+
+// CHECK: @__block_global_0.test = internal global i32
+int (^block)(void) = ^ {
+       static int test=0;
+       return test;
+};
+// CHECK: @__block_global_1.test = internal global i32
+void (^block1)(void) = ^ {
+       static int test = 2;
+       return;
+};
+// CHECK: @__block_global_2.test = internal global i32
+int (^block2)(void) = ^ {
+       static int test = 5;
+       return test;
+};
+