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).

llvm-svn: 113307
This commit is contained in:
Fariborz Jahanian 2010-09-07 23:26:17 +00:00
parent a4d9c78aa1
commit 366a94822b
3 changed files with 62 additions and 5 deletions

View 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.
//

View 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?");

View File

@ -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