]> granicus.if.org Git - clang/commitdiff
Local static block variable referecned in its
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 7 Sep 2010 23:26:17 +0000 (23:26 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 7 Sep 2010 23:26:17 +0000 (23:26 +0000)
block-literal initializer expression causes IRgen to crash.
This patch fixes by saving it in StaticLocalDecl map
already used for such purposes. (radar 8390455).

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

lib/CodeGen/CGDecl.cpp
lib/CodeGen/CGExpr.cpp
test/CodeGenObjC/local-static-block.m [new file with mode: 0644]

index 57e5236c67e5fb7b1bdd2fe910e73568fd43c518..97c03410871418b019ac955fd23c7ebb0319c37b 100644 (file)
@@ -244,6 +244,10 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
   // Make sure to evaluate VLA bounds now so that we have them for later.
   if (D.getType()->isVariablyModifiedType())
     EmitVLASize(D.getType());
+  
+  // Local static block variables must be treated as globals as they may be
+  // referenced in their RHS initializer block-literal expresion.
+  CGM.setStaticLocalDeclAddress(&D, GV);
 
   // If this value has an initializer, emit it.
   if (D.getInit())
@@ -266,9 +270,6 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
   if (D.hasAttr<UsedAttr>())
     CGM.AddUsedGlobal(GV);
 
-  if (getContext().getLangOptions().CPlusPlus)
-    CGM.setStaticLocalDeclAddress(&D, GV);
-  
   // We may have to cast the constant because of the initializer
   // mismatch above.
   //
index dacc04f5997a076d98b2969e7171bb591c72e588..bb0462f963506a75dd6d6e330cbf824b17bb8968 100644 (file)
@@ -1152,8 +1152,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
     bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr<BlocksAttr>();
 
     llvm::Value *V = LocalDeclMap[VD];
-    if (!V && getContext().getLangOptions().CPlusPlus &&
-        VD->isStaticLocal()) 
+    if (!V && VD->isStaticLocal()) 
       V = CGM.getStaticLocalDeclAddress(VD);
     assert(V && "DeclRefExpr not entered in LocalDeclMap?");
 
diff --git a/test/CodeGenObjC/local-static-block.m b/test/CodeGenObjC/local-static-block.m
new file mode 100644 (file)
index 0000000..a40abb2
--- /dev/null
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin -emit-llvm %s -o %t-64.ll
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.ll %s
+// rdar: // 8390455
+
+@class NSArray;
+
+static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
+
+  for(id rawAddress in addresses)
+  {
+   NSArray *separatedAddresses = ((NSArray*)0);
+   separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
+  }
+  return (NSArray *)0;
+};
+
+void FUNC()
+{
+ static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
+
+  for(id rawAddress in addresses)
+  {
+   NSArray *separatedAddresses = ((NSArray*)0);
+   separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
+  }
+  return (NSArray *)0;
+ };
+
+ if (ArrayRecurs) {
+   static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
+
+     for(id rawAddress in addresses)
+     {
+       NSArray *separatedAddresses = ((NSArray*)0);
+       separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
+     }
+     return (NSArray *)0;
+   };
+ }
+}
+
+void FUNC1()
+{
+ static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
+
+  for(id rawAddress in addresses)
+  {
+   NSArray *separatedAddresses = ((NSArray*)0);
+   separatedAddresses = ArrayRecurs((NSArray *)rawAddress, level+1);
+  }
+  return (NSArray *)0;
+ };
+}
+// CHECK-LP64: @ArrayRecurs = internal global
+// CHECK-LP64: @FUNC.ArrayRecurs = internal global
+// CHECK-LP64: @FUNC.ArrayRecurs3 = internal global
+// CHECK-LP64: @FUNC1.ArrayRecurs = internal global