# HG changeset patch # User Frits van Bommel # Date 1238537601 -7200 # Node ID 7562457bb7f334b55a72fae935df88906df30de4 # Parent a6dbd571d417d503b9b09f78e9160e6ff9916bd3# Parent 8baf611f000916171a9f90f33bf49616ab255ad4 Automated merge with http://hg.dsource.org/projects/ldc diff -r a6dbd571d417 -r 7562457bb7f3 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Tue Mar 31 20:21:28 2009 +0200 +++ b/gen/llvmhelpers.cpp Wed Apr 01 00:13:21 2009 +0200 @@ -1075,7 +1075,7 @@ } // does pretty much the same as DtoDeclarationExp, except it doesn't initialize, and only handles var declarations -LLValue* DtoRawVarDeclaration(VarDeclaration* var) +LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr) { // we don't handle globals with this one assert(!var->isDataseg()); @@ -1083,10 +1083,6 @@ // we don't handle aliases either assert(!var->aliassym); - // if this already has storage, it must've been handled already - if (var->ir.irLocal && var->ir.irLocal->value) - return var->ir.irLocal->value; - // referenced by nested function? #if DMDV2 if (var->nestedrefs.dim) @@ -1095,10 +1091,10 @@ #endif { assert(var->ir.irLocal); - assert(!var->ir.irLocal->value); - - // alloca - var->ir.irLocal->value = DtoAlloca(DtoType(var->type), var->toChars()); + if(!var->ir.irLocal->value) + var->ir.irLocal->value = addr ? addr : DtoAlloca(DtoType(var->type), var->toChars()); + else + assert(!addr || addr == var->ir.irLocal->value); // store the address into the nested vars array assert(var->ir.irLocal->nestedIndex >= 0); @@ -1110,9 +1106,15 @@ // normal local variable else { + // if this already has storage, it must've been handled already + if (var->ir.irLocal && var->ir.irLocal->value) { + assert(!addr || addr == var->ir.irLocal->value); + return var->ir.irLocal->value; + } + assert(!var->ir.isSet()); var->ir.irLocal = new IrLocal(var); - var->ir.irLocal->value = DtoAlloca(DtoType(var->type), var->toChars()); + var->ir.irLocal->value = addr ? addr : DtoAlloca(DtoType(var->type), var->toChars()); } // add debug info diff -r a6dbd571d417 -r 7562457bb7f3 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Tue Mar 31 20:21:28 2009 +0200 +++ b/gen/llvmhelpers.h Wed Apr 01 00:13:21 2009 +0200 @@ -101,7 +101,7 @@ // declaration inside a declarationexp DValue* DtoDeclarationExp(Dsymbol* declaration); -LLValue* DtoRawVarDeclaration(VarDeclaration* var); +LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr = 0); // initializer helpers LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init); diff -r a6dbd571d417 -r 7562457bb7f3 gen/statements.cpp --- a/gen/statements.cpp Tue Mar 31 20:21:28 2009 +0200 +++ b/gen/statements.cpp Wed Apr 01 00:13:21 2009 +0200 @@ -1030,11 +1030,12 @@ // value Logger::println("value = %s", value->toPrettyChars()); - DtoRawVarDeclaration(value); - const LLType* valtype = DtoType(value->type); LLValue* valvar = NULL; - if (!value->isRef() && !value->isOut()) + if (!value->isRef() && !value->isOut()) { + // Create a local variable to serve as the value. + DtoRawVarDeclaration(value); valvar = value->ir.irLocal->value; + } // what to iterate DValue* aggrval = aggr->toElem(p); @@ -1093,13 +1094,17 @@ // get value for this iteration LLConstant* zero = llvm::ConstantInt::get(keytype,0,false); LLValue* loadedKey = p->ir->CreateLoad(keyvar,"tmp"); - value->ir.irLocal->value = DtoGEP1(val,loadedKey); + LLValue* gep = DtoGEP1(val,loadedKey); if (!value->isRef() && !value->isOut()) { + // Copy value to local variable, and use it as the value variable. DVarValue dst(value->type, valvar); - DVarValue src(value->type, value->ir.irLocal->value); + DVarValue src(value->type, gep); DtoAssign(loc, &dst, &src); value->ir.irLocal->value = valvar; + } else { + // Use the GEP as the address of the value variable. + DtoRawVarDeclaration(value, gep); } // emit body diff -r a6dbd571d417 -r 7562457bb7f3 tests/mini/compile_rawvardeclinfinally.d --- a/tests/mini/compile_rawvardeclinfinally.d Tue Mar 31 20:21:28 2009 +0200 +++ b/tests/mini/compile_rawvardeclinfinally.d Wed Apr 01 00:13:21 2009 +0200 @@ -1,1 +1,8 @@ -void foo() { void delegate()[] bar; try {} finally { foreach (dg; bar) dg(); } } +void foo() { + void delegate()[] bar; + try { + } finally { + foreach (dg; bar) + dg(); + } +} diff -r a6dbd571d417 -r 7562457bb7f3 tests/mini/foreach10.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/foreach10.d Wed Apr 01 00:13:21 2009 +0200 @@ -0,0 +1,19 @@ +module foreach10; + +extern(C) int printf(char*, ...); + +void main() { + char* last = null; + printf("The addresses should increment:\n"); + foreach (ref c; "bar") { + auto a = { + printf("%x '%c'\n", c, c); + return &c; + }; + auto nw = a(); + printf("ptr = %p\n", nw); + if (last != null) + assert(nw == last+1); + last = nw; + } +} diff -r a6dbd571d417 -r 7562457bb7f3 tests/mini/foreach11.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/foreach11.d Wed Apr 01 00:13:21 2009 +0200 @@ -0,0 +1,18 @@ +module foreach11; + +extern(C) int printf(char*, ...); + +void main() { + char* last = null; + printf("The addresses should remain constant:\n"); + foreach (c; "bar") { + auto a = { + printf("%x '%c'\n", c, c); + printf("ptr = %p\n", &c); + if (last) + assert(last == &c); + }; + a(); + last = &c; + } +}