From d8f021d63ff323b171b648b592f70634bdf857c7 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Wed, 31 Oct 2007 20:50:21 +0100 Subject: [PATCH] [svn r82] Fixed: Fall-through switch cases were broken. --- demos/qd.d | 11 +++++++---- gen/statements.c | 11 +++++------ gen/toir.c | 18 +++--------------- gen/tollvm.c | 16 ++++++++++++---- test/bug42.d | 10 ++++++++++ test/bug43.d | 16 ++++++++++++++++ test/union6.d | 22 ++++++++++++++++++++++ 7 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 test/bug42.d create mode 100644 test/bug43.d create mode 100644 test/union6.d diff --git a/demos/qd.d b/demos/qd.d index 81794e19..c434aede 100644 --- a/demos/qd.d +++ b/demos/qd.d @@ -1,6 +1,5 @@ module qd; -/* import std.c.time: sleep; void main() { screen(640, 480); @@ -18,7 +17,6 @@ void main() { pset(10, 10); sleep(5); } -*/ extern(C) { struct SDL_Rect { @@ -308,8 +306,13 @@ void line(T...)(int x0, int y0, int x1, int y1, T p) { } } -import llvm.intrinsic; -alias llvm_sqrt sqrt; +pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f32") { + float sqrt(float val); +} +pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f64") { + double sqrt(double val); + real sqrt(real val); +} template circle_bresenham_pass(bool first) { const string xy=(first?"x":"y"); diff --git a/gen/statements.c b/gen/statements.c index 543a3b67..51010452 100644 --- a/gen/statements.c +++ b/gen/statements.c @@ -255,6 +255,7 @@ void WhileStatement::toIR(IRState* p) // create while blocks llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* whilebb = new llvm::BasicBlock("whilecond", gIR->topfunc(), oldend); + llvm::BasicBlock* whilebodybb = new llvm::BasicBlock("whilebody", gIR->topfunc(), oldend); llvm::BasicBlock* endbb = new llvm::BasicBlock("endwhile", gIR->topfunc(), oldend); // move into the while block @@ -269,11 +270,8 @@ void WhileStatement::toIR(IRState* p) llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue()); delete cond_e; - // while body block - llvm::BasicBlock* whilebodybb = new llvm::BasicBlock("whilebody", gIR->topfunc(), endbb); - // conditional branch - llvm::Value* ifbreak = new llvm::BranchInst(whilebodybb, endbb, cond_val, whilebb); + llvm::Value* ifbreak = new llvm::BranchInst(whilebodybb, endbb, cond_val, p->scopebb()); // rewrite scope gIR->scope() = IRScope(whilebodybb,endbb); @@ -580,7 +578,7 @@ void SwitchStatement::toIR(IRState* p) p->loopbbs.pop_back(); llvm::BasicBlock* curbb = p->scopebb(); - if (!curbb->empty() && !curbb->back().isTerminator()) + if (curbb->empty() || !curbb->back().isTerminator()) { new llvm::BranchInst(nextbb, curbb); } @@ -591,11 +589,12 @@ void SwitchStatement::toIR(IRState* p) { p->scope() = IRScope(defbb,endbb); p->loopbbs.push_back(IRScope(defbb,endbb)); + Logger::println("doing default statement"); sdefault->statement->toIR(p); p->loopbbs.pop_back(); llvm::BasicBlock* curbb = p->scopebb(); - if (!curbb->empty() && !curbb->back().isTerminator()) + if (curbb->empty() || !curbb->back().isTerminator()) { new llvm::BranchInst(endbb, curbb); } diff --git a/gen/toir.c b/gen/toir.c index 439f8b70..cc2cea5b 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -1445,6 +1445,7 @@ elem* SymOffExp::toElem(IRState* p) llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue; if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { + Logger::println("struct"); TypeStruct* vdt = (TypeStruct*)vdtype; assert(vdt->sym); e = new elem; @@ -1455,26 +1456,12 @@ elem* SymOffExp::toElem(IRState* p) else { std::vector dst; e->mem = LLVM_DtoIndexStruct(llvalue,vdt->sym, tnext, offset, dst); - /*size_t fo = vdt->sym->offsetToIndex(tnext, offset, dst); - llvm::Value* ptr = llvalue; - assert(ptr); - e->mem = LLVM_DtoGEP(ptr,dst,"tmp"); - if (e->mem->getType() != llt) { - e->mem = p->ir->CreateBitCast(e->mem, llt, "tmp"); - } - if (fo == (size_t)-1) { - size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0)); - assert(offset % llt_sz == 0); - e->mem = new llvm::GetElementPtrInst(e->mem, LLVM_DtoConstUint(offset / llt_sz), "tmp", p->scopebb()); - } - else if (fo) { - e->mem = new llvm::GetElementPtrInst(e->mem, LLVM_DtoConstUint(fo), "tmp", p->scopebb()); - }*/ } e->type = elem::VAL; e->field = true; } else if (vdtype->ty == Tsarray) { + Logger::println("sarray"); e = new elem; assert(llvalue); e->arg = llvalue; @@ -1496,6 +1483,7 @@ elem* SymOffExp::toElem(IRState* p) } } else if (offset == 0) { + Logger::println("normal symoff"); e = new elem; e->type = elem::VAL; assert(llvalue); diff --git a/gen/tollvm.c b/gen/tollvm.c index 0833e972..2d571913 100644 --- a/gen/tollvm.c +++ b/gen/tollvm.c @@ -1241,12 +1241,20 @@ llvm::Value* LLVM_DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expr } } + if (fnarg && paramtype && retval->getType() != paramtype) { + // this is unfortunately needed with the way SymOffExp is overused + // and static arrays can end up being a pointer to their element type + if (arg->field) { + retval = gIR->ir->CreateBitCast(retval, paramtype, "tmp"); + } + else { + Logger::cout() << "got '" << *retval->getType() << "' expected '" << *paramtype << "'\n"; + assert(0 && "parameter type that was actually passed is invalid"); + } + } + delete arg; - if (fnarg && paramtype && retval->getType() != paramtype) { - Logger::cout() << "got '" << *retval->getType() << "' expected '" << *paramtype << "'\n"; - assert(0 && "parameter type that was actually passed is invalid"); - } return retval; } diff --git a/test/bug42.d b/test/bug42.d new file mode 100644 index 00000000..516d309f --- /dev/null +++ b/test/bug42.d @@ -0,0 +1,10 @@ +module bug42; + +void main() { + int i = 2; + switch (i) { + case 0: + case 1: + default: + } +} diff --git a/test/bug43.d b/test/bug43.d new file mode 100644 index 00000000..6014ca4c --- /dev/null +++ b/test/bug43.d @@ -0,0 +1,16 @@ +module bug43; + +struct S +{ + ubyte[3] vals; +} + +void func(ubyte[3] v) +{ +} + +void main() +{ + S s; + func(s.vals); +} diff --git a/test/union6.d b/test/union6.d new file mode 100644 index 00000000..4cd03f78 --- /dev/null +++ b/test/union6.d @@ -0,0 +1,22 @@ +module union6; + +pragma(LLVM_internal, "notypeinfo") { + struct S + { + byte a; + byte b; + } + union U + { + byte a; + byte b; + S c; + } +} + +void main() +{ + U u; + auto a = u.c.b; + //auto c = u.s.l; +}