From 9081e5574665d28705a40902875158404ccdbebd Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sat, 17 Jan 2009 14:53:32 +0100 Subject: [PATCH] Fix #163. --- gen/toir.cpp | 18 +++++++++++++----- tests/mini/bug163_void_condexp.d | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 tests/mini/bug163_void_condexp.d diff --git a/gen/toir.cpp b/gen/toir.cpp index 9d47b53e..54dac060 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2099,9 +2099,15 @@ DValue* CondExp::toElem(IRState* p) Type* dtype = type->toBasetype(); const LLType* resty = DtoType(dtype); - // allocate a temporary for the final result. failed to come up with a better way :/ - LLValue* resval = DtoAlloca(resty,"condtmp"); - DVarValue* dvv = new DVarValue(type, resval); + DValue* dvv; + // voids returns will need no storage + if (dtype->ty != Tvoid) { + // allocate a temporary for the final result. failed to come up with a better way :/ + LLValue* resval = DtoAlloca(resty,"condtmp"); + dvv = new DVarValue(type, resval); + } else { + dvv = new DConstValue(type, getNullValue(DtoTypeNotVoid(dtype))); + } llvm::BasicBlock* oldend = p->scopeend(); llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend); @@ -2114,12 +2120,14 @@ DValue* CondExp::toElem(IRState* p) p->scope() = IRScope(condtrue, condfalse); DValue* u = e1->toElem(p); - DtoAssign(loc, dvv, u); + if (dtype->ty != Tvoid) + DtoAssign(loc, dvv, u); llvm::BranchInst::Create(condend,p->scopebb()); p->scope() = IRScope(condfalse, condend); DValue* v = e2->toElem(p); - DtoAssign(loc, dvv, v); + if (dtype->ty != Tvoid) + DtoAssign(loc, dvv, v); llvm::BranchInst::Create(condend,p->scopebb()); p->scope() = IRScope(condend, oldend); diff --git a/tests/mini/bug163_void_condexp.d b/tests/mini/bug163_void_condexp.d new file mode 100644 index 00000000..8683d533 --- /dev/null +++ b/tests/mini/bug163_void_condexp.d @@ -0,0 +1,18 @@ + +static foocalled = false; +static barcalled = false; +void foo() { foocalled = true; } +void bar() { barcalled = true; } + +void f(bool b) +{ + return b ? foo() : bar(); +} + +void main() +{ + f(true); + assert(foocalled && !barcalled); + f(false); + assert(foocalled && barcalled); +}