diff --git a/gen/toir.c b/gen/toir.c index badbb3d7..fba927f4 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -137,8 +137,17 @@ elem* VarExp::toElem(IRState* p) e->type = elem::VAR; } else { - e->val = vd->llvmValue; - e->type = elem::VAL; + if (llvm::isa(vd->llvmValue)) { + e->val = vd->llvmValue; + e->type = elem::VAL; + e->vardecl = vd; + } + else if (llvm::isa(vd->llvmValue)) { + e->mem = vd->llvmValue; + e->type = elem::VAR; + } + else + assert(0); } } } @@ -322,7 +331,10 @@ elem* AssignExp::toElem(IRState* p) elem* r = e2->toElem(p); p->lvals.pop_back(); - assert(l->mem); + // handle function argument - allocate temp storage for it :/ annoying + if (l->mem == 0) { + LLVM_DtoGiveArgumentStorage(l); + } //e->val = l->store(r->getValue()); TY e1ty = e1->type->ty; @@ -516,6 +528,8 @@ elem* AddAssignExp::toElem(IRState* p) tmp = LLVM_DtoPointedType(storeVal, tmp); }*/ + if (l->mem == 0) + LLVM_DtoGiveArgumentStorage(l); new llvm::StoreInst(val,l->mem,p->scopebb()); e->type = elem::VAR; @@ -585,6 +599,8 @@ elem* MinAssignExp::toElem(IRState* p) tmp = LLVM_DtoPointedType(storeVal, tmp); }*/ + if (l->mem == 0) + LLVM_DtoGiveArgumentStorage(l); new llvm::StoreInst(tmp, l->mem, p->scopebb()); delete l; @@ -635,6 +651,8 @@ elem* MulAssignExp::toElem(IRState* p) tmp = LLVM_DtoPointedType(storeVal, tmp); }*/ + if (l->mem == 0) + LLVM_DtoGiveArgumentStorage(l); new llvm::StoreInst(tmp,l->mem,p->scopebb()); delete l; @@ -696,6 +714,8 @@ elem* DivAssignExp::toElem(IRState* p) tmp = LLVM_DtoPointedType(storeVal, tmp); }*/ + if (l->mem == 0) + LLVM_DtoGiveArgumentStorage(l); new llvm::StoreInst(tmp,l->mem,p->scopebb()); delete l; @@ -757,6 +777,8 @@ elem* ModAssignExp::toElem(IRState* p) tmp = LLVM_DtoPointedType(storeVal, tmp); }*/ + if (l->mem == 0) + LLVM_DtoGiveArgumentStorage(l); new llvm::StoreInst(tmp,l->mem,p->scopebb()); delete l; @@ -2079,6 +2101,8 @@ elem* X##AssignExp::toElem(IRState* p) \ elem* v = e2->toElem(p); \ llvm::Value* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, u->getValue(), v->getValue(), "tmp", p->scopebb()); \ Logger::cout() << *tmp << '|' << *u->mem << '\n'; \ + if (u->mem == 0) \ + LLVM_DtoGiveArgumentStorage(u); \ new llvm::StoreInst(LLVM_DtoPointedType(u->mem, tmp), u->mem, p->scopebb()); \ delete u; \ delete v; \ diff --git a/gen/tollvm.c b/gen/tollvm.c index 0ad9ca0a..1bcc037c 100644 --- a/gen/tollvm.c +++ b/gen/tollvm.c @@ -982,3 +982,17 @@ llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl) return func; } + +////////////////////////////////////////////////////////////////////////////////////////// + +void LLVM_DtoGiveArgumentStorage(elem* l) +{ + assert(l->mem == 0); + assert(l->val); + assert(llvm::isa(l->val)); + assert(l->vardecl != 0); + + llvm::AllocaInst* allocainst = new llvm::AllocaInst(l->val->getType(), l->val->getName()+"_storage", gIR->topallocapoint()); + l->mem = allocainst; + l->vardecl->llvmValue = l->mem; +} diff --git a/gen/tollvm.h b/gen/tollvm.h index 71beb1bb..a2fa1251 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -42,4 +42,6 @@ llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector& src, con llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb); llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb); +void LLVM_DtoGiveArgumentStorage(elem* e); + #include "enums.h" diff --git a/test/bug3.d b/test/bug3.d index bf000d87..4ff20475 100644 --- a/test/bug3.d +++ b/test/bug3.d @@ -6,6 +6,12 @@ struct S char[5] ch; } +class C +{ + int[] arr; + char[4] crs; +} + void main() { S s; diff --git a/test/bug4.d b/test/bug4.d new file mode 100644 index 00000000..19d1a0a4 --- /dev/null +++ b/test/bug4.d @@ -0,0 +1,13 @@ +module bug4; + +int func(int i) +{ + i += 2; + i -= 3; + return i; +} + +void main() +{ + assert(func(4) == 3); +}