From c3d517e17ff19f1cb451345d12dc3ebcd84d89e6 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Fri, 4 Jan 2013 07:26:15 +0100 Subject: [PATCH] Correctly handle ref variables in an outer frame. Fixes DMD testcase 'testcontracts'. --- gen/dvalue.cpp | 7 +++++++ gen/dvalue.h | 4 ++++ gen/toir.cpp | 8 +++----- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index 05ef76af5a..9da1644838 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 fa1982e2cf..1e91bc82b8 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 38918a3f50..cfdcb306c7 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; } }