diff gen/statements.cpp @ 1185:8baf611f0009

Fix nested references to 'ref' foreach variables. These "walk around" the array being iterated over, so they're a bit trickier than other variables to get right.
author Frits van Bommel <fvbommel wxs.nl>
date Wed, 01 Apr 2009 00:01:44 +0200
parents 7d28dcbff23e
children 0686701178d3
line wrap: on
line diff
--- a/gen/statements.cpp	Tue Mar 31 03:06:19 2009 +0200
+++ b/gen/statements.cpp	Wed Apr 01 00:01:44 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