changeset 887:7f6eeb7b003e

Fix #163.
author Christian Kamm <kamm incasoftware de>
date Sat, 17 Jan 2009 14:53:32 +0100
parents 7ddd03a2ce02
children d8c44f1e08e1
files gen/toir.cpp tests/mini/bug163_void_condexp.d
diffstat 2 files changed, 31 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/gen/toir.cpp	Fri Jan 16 21:06:33 2009 +0100
+++ b/gen/toir.cpp	Sat Jan 17 14:53:32 2009 +0100
@@ -2099,9 +2099,15 @@
     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 @@
 
     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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/bug163_void_condexp.d	Sat Jan 17 14:53:32 2009 +0100
@@ -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);
+}