mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-20 04:10:18 +02:00
[svn r82] Fixed: Fall-through switch cases were broken.
This commit is contained in:
+7
-4
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
module bug42;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
int i = 2;
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
module bug43;
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
ubyte[3] vals;
|
||||||
|
}
|
||||||
|
|
||||||
|
void func(ubyte[3] v)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
S s;
|
||||||
|
func(s.vals);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user