aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-09-07 23:26:17 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-09-07 23:26:17 +0000
commit09349145d7e9b2142a9cef94e30eb8b70ce99bdc (patch)
tree858ae5d58dfee4d4788c5ea70add376536bbf16e
parentc79f767941fdfedb02d20296a042ad951a593890 (diff)
Local static block variable referecned in its
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
-rw-r--r--lib/CodeGen/CGDecl.cpp7
-rw-r--r--lib/CodeGen/CGExpr.cpp3
-rw-r--r--test/CodeGenObjC/local-static-block.m57
3 files changed, 62 insertions, 5 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 57e5236c67..97c0341087 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -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.
//
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index dacc04f599..bb0462f963 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -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
index 0000000000..a40abb26ea
--- /dev/null
+++ b/test/CodeGenObjC/local-static-block.m
@@ -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