diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index 05ef76af..9da16448 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -57,6 +57,13 @@ LLValue* DVarValue::getRVal() return DtoLoad(tmp); } +LLValue* DVarValue::getRefStorage() +{ + assert(val); + assert(isSpecialRefVar(var)); + return val; +} + ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/dvalue.h b/gen/dvalue.h index fa1982e2..1e91bc82 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -110,6 +110,10 @@ struct DVarValue : DValue virtual llvm::Value* getLVal(); virtual llvm::Value* getRVal(); + /// Returns the underlying storage for special internal ref variables. + /// Illegal to call on any other value. + virtual llvm::Value* getRefStorage(); + virtual DVarValue* isVar() { return this; } }; diff --git a/gen/toir.cpp b/gen/toir.cpp index 38918a3f..cfdcb306 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -597,12 +597,10 @@ DValue* AssignExp::toElem(IRState* p) // Note that the variable value is accessed directly (instead // of via getLValue(), which would perform a load from the // uninitialized location), and that rhs is stored as an l-value! - - IrLocal* const local = ve->var->ir.irLocal; - assert(local && "ref var must be local and already initialized"); - + DVarValue* lhs = e1->toElem(p)->isVar(); + assert(lhs); DValue* rhs = e2->toElem(p); - DtoStore(rhs->getLVal(), local->value); + DtoStore(rhs->getLVal(), lhs->getRefStorage()); return rhs; } }