From 58b6fc972a846e9be80e0aac1ee1ec318b6b51c0 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sun, 28 Oct 2007 04:23:38 +0100 Subject: [PATCH] [svn r73] Identity expression for dynamic array and null was broken. --- gen/arrays.c | 41 ++++++++++++++++++++++++++++------------- gen/arrays.h | 4 ++-- gen/toir.c | 18 +++++++++++------- gen/tollvm.c | 2 +- gen/toobj.c | 2 +- gen/typinf.c | 19 ++++++++++++++++--- test/bug37.d | 7 +++++++ test/typeinfo3.d | 1 + test/typeinfo9.d | 10 ++++++++++ 9 files changed, 77 insertions(+), 27 deletions(-) create mode 100644 test/bug37.d create mode 100644 test/typeinfo9.d diff --git a/gen/arrays.c b/gen/arrays.c index a48bea68..60d78f52 100644 --- a/gen/arrays.c +++ b/gen/arrays.c @@ -409,7 +409,7 @@ void LLVM_DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src) } ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr) +llvm::Constant* LLVM_DtoConstSlice(llvm::Constant* dim, llvm::Constant* ptr) { std::vector types; types.push_back(dim->getType()); @@ -622,31 +622,46 @@ llvm::Value* LLVM_DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, ////////////////////////////////////////////////////////////////////////////////////////// llvm::Value* LLVM_DtoDynArrayIs(TOK op, llvm::Value* l, llvm::Value* r) { - assert(l->getType() == r->getType()); - llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; - llvm::Value* ll = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,0, "tmp"),"tmp"); - llvm::Value* rl = gIR->ir->CreateLoad(LLVM_DtoGEPi(r, 0,0, "tmp"),"tmp"); - llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); + if (r == NULL) { + llvm::Value* ll = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,0, "tmp"),"tmp"); + llvm::Value* rl = LLVM_DtoConstSize_t(0); + llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); - llvm::Value* lp = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,1, "tmp"),"tmp"); - llvm::Value* rp = gIR->ir->CreateLoad(LLVM_DtoGEPi(r, 0,1, "tmp"),"tmp"); - llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); + llvm::Value* lp = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,1, "tmp"),"tmp"); + const llvm::PointerType* pty = llvm::cast(lp->getType()); + llvm::Value* rp = llvm::ConstantPointerNull::get(pty); + llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); - llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); - return b; + llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); + return b; + } + else { + assert(l->getType() == r->getType()); + + llvm::Value* ll = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,0, "tmp"),"tmp"); + llvm::Value* rl = gIR->ir->CreateLoad(LLVM_DtoGEPi(r, 0,0, "tmp"),"tmp"); + llvm::Value* b1 = gIR->ir->CreateICmp(pred,ll,rl,"tmp"); + + llvm::Value* lp = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,1, "tmp"),"tmp"); + llvm::Value* rp = gIR->ir->CreateLoad(LLVM_DtoGEPi(r, 0,1, "tmp"),"tmp"); + llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp"); + + llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); + return b; + } } ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Constant* LLVM_DtoConstantStaticArray(const llvm::Type* t, llvm::Constant* c) +llvm::Constant* LLVM_DtoConstStaticArray(const llvm::Type* t, llvm::Constant* c) { assert(llvm::isa(t)); const llvm::ArrayType* at = llvm::cast(t); if (llvm::isa(at->getElementType())) { - c = LLVM_DtoConstantStaticArray(at->getElementType(), c); + c = LLVM_DtoConstStaticArray(at->getElementType(), c); } else { assert(at->getElementType() == c->getType()); diff --git a/gen/arrays.h b/gen/arrays.h index f68c9c03..5c85dc63 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -5,8 +5,8 @@ const llvm::StructType* LLVM_DtoArrayType(Type* t); const llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t); llvm::Constant* LLVM_DtoConstArrayInitializer(ArrayInitializer* si); -llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr); -llvm::Constant* LLVM_DtoConstantStaticArray(const llvm::Type* t, llvm::Constant* c); +llvm::Constant* LLVM_DtoConstSlice(llvm::Constant* dim, llvm::Constant* ptr); +llvm::Constant* LLVM_DtoConstStaticArray(const llvm::Type* t, llvm::Constant* c); void LLVM_DtoArrayCopy(elem* dst, elem* src); void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r); diff --git a/gen/toir.c b/gen/toir.c index f9c5d2dc..d71b6d48 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -425,7 +425,7 @@ llvm::Constant* StringExp::toConstElem(IRState* p) if (t->ty == Tarray) { llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); - return LLVM_DtoConstantSlice(clen, arrptr); + return LLVM_DtoConstSlice(clen, arrptr); } assert(0); @@ -2539,20 +2539,24 @@ elem* IdentityExp::toElem(IRState* p) elem* e = new elem; llvm::Value* l = u->getValue(); - llvm::Value* r = 0; - if (v->type == elem::NUL) - r = llvm::ConstantPointerNull::get(llvm::cast(l->getType())); - else - r = v->getValue(); + llvm::Value* r = v->getValue(); Type* t1 = LLVM_DtoDType(e1->type); if (t1->ty == Tarray) { - assert(l->getType() == r->getType()); + if (v->type == elem::NUL) { + r = NULL; + } + else { + assert(l->getType() == r->getType()); + } e->val = LLVM_DtoDynArrayIs(op,l,r); } else { llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; + if (t1->ty == Tpointer && v->type == elem::NUL && l->getType() != r->getType()) { + r = llvm::ConstantPointerNull::get(llvm::cast(l->getType())); + } e->val = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); } e->type = elem::VAL; diff --git a/gen/tollvm.c b/gen/tollvm.c index 2cd7e95b..45c9aa1e 100644 --- a/gen/tollvm.c +++ b/gen/tollvm.c @@ -1392,7 +1392,7 @@ llvm::Constant* LLVM_DtoConstString(const char* str) llvm::GlobalVariable* gvar = new llvm::GlobalVariable( init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); llvm::Constant* idxs[2] = { LLVM_DtoConstUint(0), LLVM_DtoConstUint(0) }; - return LLVM_DtoConstantSlice( + return LLVM_DtoConstSlice( LLVM_DtoConstSize_t(s.length()), llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) ); diff --git a/gen/toobj.c b/gen/toobj.c index a5693a24..f26e4197 100644 --- a/gen/toobj.c +++ b/gen/toobj.c @@ -547,7 +547,7 @@ void VarDeclaration::toObjFile() // array single value init else if (llvm::isa(_type)) { - _init = LLVM_DtoConstantStaticArray(_type, _init); + _init = LLVM_DtoConstStaticArray(_type, _init); } else { Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; diff --git a/gen/typinf.c b/gen/typinf.c index 1798fa3d..905ccd8e 100644 --- a/gen/typinf.c +++ b/gen/typinf.c @@ -312,9 +312,22 @@ void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) assert(sinits.back()->getType() == initZ->getOperand(2)->getType()); // void[] init - //const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty); - //sinits.push_back(LLVM_DtoConstantSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); - sinits.push_back(initZ->getOperand(3)); + const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty); + if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type + { + sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); + //sinits.push_back(initZ->getOperand(3)); + } + else + { + llvm::Constant* ci = LLVM_DtoConstInitializer(sd->basetype, sd->init); + std::string ciname(sd->mangle()); + ciname.append("__init"); + llvm::GlobalVariable* civar = new llvm::GlobalVariable(LLVM_DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module); + llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt); + size_t cisize = gTargetData->getTypeSize(LLVM_DtoType(sd->basetype)); + sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(cisize), cicast)); + } // create the symbol llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); diff --git a/test/bug37.d b/test/bug37.d new file mode 100644 index 00000000..edb83c86 --- /dev/null +++ b/test/bug37.d @@ -0,0 +1,7 @@ +module bug37; + +void main() +{ + char[] a = "hello"; + assert(a !is null); +} diff --git a/test/typeinfo3.d b/test/typeinfo3.d index 9c4e949c..a56dea82 100644 --- a/test/typeinfo3.d +++ b/test/typeinfo3.d @@ -10,4 +10,5 @@ void main() assert(ti.toString() == "typeinfo3.int_t"); assert(ti.next !is null); assert(ti.next.toString() == "int"); + assert(ti.init is null); } diff --git a/test/typeinfo9.d b/test/typeinfo9.d new file mode 100644 index 00000000..42141c6f --- /dev/null +++ b/test/typeinfo9.d @@ -0,0 +1,10 @@ +module typeinfo9; + +typedef int int_t = 42; + +void main() +{ + auto i = typeid(int_t).init; + assert(i.length == int_t.sizeof); + assert(*cast(int_t*)i.ptr == 42); +}