[svn r82] Fixed: Fall-through switch cases were broken.

This commit is contained in:
Tomas Lindquist Olsen
2007-10-31 20:50:21 +01:00
parent 0979d55d26
commit d8f021d63f
7 changed files with 75 additions and 29 deletions
+7 -4
View File
@@ -1,6 +1,5 @@
module qd; module qd;
/*
import std.c.time: sleep; import std.c.time: sleep;
void main() { void main() {
screen(640, 480); screen(640, 480);
@@ -18,7 +17,6 @@ void main() {
pset(10, 10); pset(10, 10);
sleep(5); sleep(5);
} }
*/
extern(C) { extern(C) {
struct SDL_Rect { struct SDL_Rect {
@@ -308,8 +306,13 @@ void line(T...)(int x0, int y0, int x1, int y1, T p) {
} }
} }
import llvm.intrinsic; pragma(LLVM_internal, "intrinsic", "llvm.sqrt.f32") {
alias llvm_sqrt sqrt; 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) { template circle_bresenham_pass(bool first) {
const string xy=(first?"x":"y"); const string xy=(first?"x":"y");
+5 -6
View File
@@ -255,6 +255,7 @@ void WhileStatement::toIR(IRState* p)
// create while blocks // create while blocks
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* whilebb = new llvm::BasicBlock("whilecond", gIR->topfunc(), oldend); 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); llvm::BasicBlock* endbb = new llvm::BasicBlock("endwhile", gIR->topfunc(), oldend);
// move into the while block // move into the while block
@@ -269,11 +270,8 @@ void WhileStatement::toIR(IRState* p)
llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue()); llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue());
delete cond_e; delete cond_e;
// while body block
llvm::BasicBlock* whilebodybb = new llvm::BasicBlock("whilebody", gIR->topfunc(), endbb);
// conditional branch // 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 // rewrite scope
gIR->scope() = IRScope(whilebodybb,endbb); gIR->scope() = IRScope(whilebodybb,endbb);
@@ -580,7 +578,7 @@ void SwitchStatement::toIR(IRState* p)
p->loopbbs.pop_back(); p->loopbbs.pop_back();
llvm::BasicBlock* curbb = p->scopebb(); llvm::BasicBlock* curbb = p->scopebb();
if (!curbb->empty() && !curbb->back().isTerminator()) if (curbb->empty() || !curbb->back().isTerminator())
{ {
new llvm::BranchInst(nextbb, curbb); new llvm::BranchInst(nextbb, curbb);
} }
@@ -591,11 +589,12 @@ void SwitchStatement::toIR(IRState* p)
{ {
p->scope() = IRScope(defbb,endbb); p->scope() = IRScope(defbb,endbb);
p->loopbbs.push_back(IRScope(defbb,endbb)); p->loopbbs.push_back(IRScope(defbb,endbb));
Logger::println("doing default statement");
sdefault->statement->toIR(p); sdefault->statement->toIR(p);
p->loopbbs.pop_back(); p->loopbbs.pop_back();
llvm::BasicBlock* curbb = p->scopebb(); llvm::BasicBlock* curbb = p->scopebb();
if (!curbb->empty() && !curbb->back().isTerminator()) if (curbb->empty() || !curbb->back().isTerminator())
{ {
new llvm::BranchInst(endbb, curbb); new llvm::BranchInst(endbb, curbb);
} }
+3 -15
View File
@@ -1445,6 +1445,7 @@ elem* SymOffExp::toElem(IRState* p)
llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue; llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue;
if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) {
Logger::println("struct");
TypeStruct* vdt = (TypeStruct*)vdtype; TypeStruct* vdt = (TypeStruct*)vdtype;
assert(vdt->sym); assert(vdt->sym);
e = new elem; e = new elem;
@@ -1455,26 +1456,12 @@ elem* SymOffExp::toElem(IRState* p)
else { else {
std::vector<unsigned> dst; std::vector<unsigned> dst;
e->mem = LLVM_DtoIndexStruct(llvalue,vdt->sym, tnext, offset, 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->type = elem::VAL;
e->field = true; e->field = true;
} }
else if (vdtype->ty == Tsarray) { else if (vdtype->ty == Tsarray) {
Logger::println("sarray");
e = new elem; e = new elem;
assert(llvalue); assert(llvalue);
e->arg = llvalue; e->arg = llvalue;
@@ -1496,6 +1483,7 @@ elem* SymOffExp::toElem(IRState* p)
} }
} }
else if (offset == 0) { else if (offset == 0) {
Logger::println("normal symoff");
e = new elem; e = new elem;
e->type = elem::VAL; e->type = elem::VAL;
assert(llvalue); assert(llvalue);
+12 -4
View File
@@ -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; 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; return retval;
} }
+10
View File
@@ -0,0 +1,10 @@
module bug42;
void main() {
int i = 2;
switch (i) {
case 0:
case 1:
default:
}
}
+16
View File
@@ -0,0 +1,16 @@
module bug43;
struct S
{
ubyte[3] vals;
}
void func(ubyte[3] v)
{
}
void main()
{
S s;
func(s.vals);
}
+22
View File
@@ -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;
}