[svn r349] Fixed problems with static arrays of void as well as a static arrays with zero length.

Fixed issues with DMD generated assert statements when using class invariants, generally due to incomplete ASTs.
Removed some dead code.
Added a few comments.
This commit is contained in:
Tomas Lindquist Olsen 2008-07-11 00:17:00 +02:00
parent bace4dd0e7
commit 521de1a47e
8 changed files with 56 additions and 89 deletions

View file

@ -7682,6 +7682,8 @@ Expression *MinExp::semantic(Scope *sc)
typeCombine(sc); // make sure pointer types are compatible typeCombine(sc); // make sure pointer types are compatible
type = Type::tptrdiff_t; type = Type::tptrdiff_t;
stride = t2->next->size(); stride = t2->next->size();
if (!stride)
return new IntegerExp(0, 0, Type::tptrdiff_t);
e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t)); e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t));
e->type = Type::tptrdiff_t; e->type = Type::tptrdiff_t;
return e; return e;

View file

@ -34,21 +34,16 @@ const LLStructType* DtoArrayType(const LLType* t)
const LLArrayType* DtoStaticArrayType(Type* t) const LLArrayType* DtoStaticArrayType(Type* t)
{ {
if (t->ir.type) t = t->toBasetype();
return isaArray(t->ir.type->get());
assert(t->ty == Tsarray); assert(t->ty == Tsarray);
assert(t->next);
const LLType* at = DtoType(t->next);
TypeSArray* tsa = (TypeSArray*)t; TypeSArray* tsa = (TypeSArray*)t;
assert(tsa->dim->type->isintegral()); Type* tnext = tsa->next;
const LLArrayType* arrty = LLArrayType::get(at,tsa->dim->toUInteger());
assert(!tsa->ir.type); const LLType* elemty = DtoType(tnext);
tsa->ir.type = new LLPATypeHolder(arrty); if (elemty == LLType::VoidTy)
return arrty; elemty = LLType::Int8Ty;
return LLArrayType::get(elemty, tsa->dim->toUInteger());
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -974,14 +969,8 @@ DValue* DtoCastArray(DValue* u, Type* to)
} }
else if (totype->ty == Tarray) { else if (totype->ty == Tarray) {
Logger::cout() << "to array" << '\n'; Logger::cout() << "to array" << '\n';
const LLType* ptrty = DtoType(totype->next); const LLType* ptrty = DtoArrayType(totype)->getContainedType(1);
if (ptrty == LLType::VoidTy) const LLType* ety = DtoTypeNotVoid(fromtype->next);
ptrty = LLType::Int8Ty;
ptrty = getPtrToType(ptrty);
const LLType* ety = DtoType(fromtype->next);
if (ety == LLType::VoidTy)
ety = LLType::Int8Ty;
if (DSliceValue* usl = u->isSlice()) { if (DSliceValue* usl = u->isSlice()) {
Logger::println("from slice"); Logger::println("from slice");

View file

@ -1336,46 +1336,6 @@ static LLConstant* build_offti_array(ClassDeclaration* cd, LLConstant* init)
static LLConstant* build_class_dtor(ClassDeclaration* cd) static LLConstant* build_class_dtor(ClassDeclaration* cd)
{ {
#if 0
// construct the function
std::vector<const LLType*> paramTypes;
paramTypes.push_back(getPtrToType(cd->type->ir.type->get()));
const llvm::FunctionType* fnTy = llvm::FunctionType::get(LLType::VoidTy, paramTypes, false);
if (cd->dtors.dim == 0) {
return llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty));
}
else if (cd->dtors.dim == 1) {
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
DtoForceDeclareDsymbol(d);
assert(d->ir.irFunc->func);
return llvm::ConstantExpr::getBitCast(isaConstant(d->ir.irFunc->func), getPtrToType(LLType::Int8Ty));
}
std::string gname("_D");
gname.append(cd->mangle());
gname.append("12__destructorMFZv");
llvm::Function* func = llvm::Function::Create(fnTy, DtoInternalLinkage(cd), gname, gIR->module);
LLValue* thisptr = func->arg_begin();
thisptr->setName("this");
llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", func);
IRBuilder builder(bb);
for (size_t i = 0; i < cd->dtors.dim; i++)
{
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
DtoForceDeclareDsymbol(d);
assert(d->ir.irFunc->func);
gIR->CreateCallOrInvoke(d->ir.irFunc->func, thisptr);
}
builder.CreateRetVoid();
return llvm::ConstantExpr::getBitCast(func, getPtrToType(LLType::Int8Ty));
#else
FuncDeclaration* dtor = cd->dtor; FuncDeclaration* dtor = cd->dtor;
// if no destructor emit a null // if no destructor emit a null
@ -1384,7 +1344,6 @@ static LLConstant* build_class_dtor(ClassDeclaration* cd)
DtoForceDeclareDsymbol(dtor); DtoForceDeclareDsymbol(dtor);
return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty)); return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
#endif
} }
static unsigned build_classinfo_flags(ClassDeclaration* cd) static unsigned build_classinfo_flags(ClassDeclaration* cd)
@ -1556,7 +1515,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
if (cd->inv) { if (cd->inv) {
DtoForceDeclareDsymbol(cd->inv); DtoForceDeclareDsymbol(cd->inv);
c = cd->inv->ir.irFunc->func; c = cd->inv->ir.irFunc->func;
// c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(8)->getType()); c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(8)->getType());
} }
else { else {
c = defc->getOperand(8); c = defc->getOperand(8);

View file

@ -732,22 +732,9 @@ void DtoDefineFunc(FuncDeclaration* fd)
// if the last block is empty now, it must be unreachable or it's a bug somewhere else // if the last block is empty now, it must be unreachable or it's a bug somewhere else
// would be nice to figure out how to assert that this is correct // would be nice to figure out how to assert that this is correct
llvm::BasicBlock* lastbb = &func->getBasicBlockList().back(); llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
if (lastbb->empty()) { if (lastbb->empty())
{
new llvm::UnreachableInst(lastbb); new llvm::UnreachableInst(lastbb);
// if (llvm::pred_begin(lastbb) != llvm::pred_end(lastbb))
// {
// Logger::println("Erasing lastbb");
// lastbb->eraseFromParent();
// }
// else {
// new llvm::UnreachableInst(lastbb);
// // if (func->getReturnType() == LLType::VoidTy) {
// // llvm::ReturnInst::Create(lastbb);
// // }
// // else {
// // llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb);
// // }
// }
} }
// if the last block is not terminated we return a null value or void // if the last block is not terminated we return a null value or void

View file

@ -1210,7 +1210,9 @@ LLConstant* DtoConstFieldInitializer(Type* t, Initializer* init)
DValue* DtoInitializer(Initializer* init) DValue* DtoInitializer(Initializer* init)
{ {
if (ExpInitializer* ex = init->isExpInitializer()) if (!init)
return 0;
else if (ExpInitializer* ex = init->isExpInitializer())
{ {
Logger::println("expression initializer"); Logger::println("expression initializer");
assert(ex->exp); assert(ex->exp);

View file

@ -73,12 +73,13 @@ DValue* DeclarationExp::toElem(IRState* p)
else { else {
// allocate storage on the stack // allocate storage on the stack
const LLType* lltype = DtoType(vd->type); const LLType* lltype = DtoType(vd->type);
llvm::Value* allocainst;
if(gTargetData->getTypeSizeInBits(lltype) == 0) if(gTargetData->getTypeSizeInBits(lltype) == 0)
{ allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
error("Allocating a variable of type %s and size zero is not implemented. (the behaviour of alloca with zero size is undefined)", vd->type->toChars()); else
fatal(); allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
}
llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
//allocainst->setAlignment(vd->type->alignsize()); // TODO //allocainst->setAlignment(vd->type->alignsize()); // TODO
assert(!vd->ir.irLocal); assert(!vd->ir.irLocal);
vd->ir.irLocal = new IrLocal(vd); vd->ir.irLocal = new IrLocal(vd);
@ -428,9 +429,7 @@ DValue* StringExp::toElem(IRState* p)
Type* dtype = DtoDType(type); Type* dtype = DtoDType(type);
Type* cty = DtoDType(dtype->next); Type* cty = DtoDType(dtype->next);
const LLType* ct = DtoType(cty); const LLType* ct = DtoTypeNotVoid(cty);
if (ct == LLType::VoidTy)
ct = LLType::Int8Ty;
//printf("ct = %s\n", type->next->toChars()); //printf("ct = %s\n", type->next->toChars());
const LLArrayType* at = LLArrayType::get(ct,len+1); const LLArrayType* at = LLArrayType::get(ct,len+1);
@ -1484,7 +1483,16 @@ DValue* ThisExp::toElem(IRState* p)
Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE; LOG_SCOPE;
if (VarDeclaration* vd = var->isVarDeclaration()) { // this seems to happen for dmd generated assert statements like:
// assert(this, "null this");
if (!var)
{
LLValue* v = p->func()->thisVar;
assert(v);
return new DImValue(type, v);
}
// regular this expr
else if (VarDeclaration* vd = var->isVarDeclaration()) {
LLValue* v; LLValue* v;
v = p->func()->decl->ir.irFunc->thisVar; v = p->func()->decl->ir.irFunc->thisVar;
if (llvm::isa<llvm::AllocaInst>(v)) if (llvm::isa<llvm::AllocaInst>(v))
@ -1495,6 +1503,7 @@ DValue* ThisExp::toElem(IRState* p)
return new DThisValue(vd, v); return new DThisValue(vd, v);
} }
// anything we're not yet handling ?
assert(0); assert(0);
return 0; return 0;
} }
@ -2005,7 +2014,7 @@ DValue* ArrayLengthExp::toElem(IRState* p)
DValue* AssertExp::toElem(IRState* p) DValue* AssertExp::toElem(IRState* p)
{ {
Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars()); Logger::print("AssertExp::toElem: %s\n", toChars());
LOG_SCOPE; LOG_SCOPE;
// condition // condition

View file

@ -89,6 +89,7 @@ const LLType* DtoType(Type* t)
// pointers // pointers
case Tpointer: case Tpointer:
// getPtrToType checks for void itself
return getPtrToType(DtoType(t->next)); return getPtrToType(DtoType(t->next));
// arrays // arrays
@ -152,6 +153,7 @@ const LLType* DtoType(Type* t)
case Taarray: case Taarray:
{ {
TypeAArray* taa = (TypeAArray*)t; TypeAArray* taa = (TypeAArray*)t;
// aa key/val can't be void
return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0)); return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0));
} }
@ -164,6 +166,16 @@ const LLType* DtoType(Type* t)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
const LLType* DtoTypeNotVoid(Type* t)
{
const LLType* lt = DtoType(t);
if (lt == LLType::VoidTy)
return LLType::Int8Ty;
return lt;
}
//////////////////////////////////////////////////////////////////////////////////////////
const LLStructType* DtoDelegateType(Type* t) const LLStructType* DtoDelegateType(Type* t)
{ {
const LLType* i8ptr = getVoidPtrType(); const LLType* i8ptr = getVoidPtrType();
@ -499,7 +511,7 @@ llvm::ConstantFP* DtoConstFP(Type* t, long double value)
LLConstant* DtoConstString(const char* str) LLConstant* DtoConstString(const char* str)
{ {
std::string s(str); std::string s(str?str:"");
LLConstant* init = llvm::ConstantArray::get(s, true); LLConstant* init = llvm::ConstantArray::get(s, true);
llvm::GlobalVariable* gvar = new llvm::GlobalVariable( llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
init->getType(), true,llvm::GlobalValue::InternalLinkage, init, ".str", gIR->module); init->getType(), true,llvm::GlobalValue::InternalLinkage, init, ".str", gIR->module);

View file

@ -11,7 +11,14 @@
// D->LLVM type handling stuff // D->LLVM type handling stuff
const LLType* DtoType(Type* t); const LLType* DtoType(Type* t);
// same as DtoType except it converts 'void' to 'i8'
const LLType* DtoTypeNotVoid(Type* t);
// returns true is the type must be passed by pointer
bool DtoIsPassedByRef(Type* type); bool DtoIsPassedByRef(Type* type);
// returns if the type should be returned in a hidden pointer arguement
bool DtoIsReturnedInArg(Type* type); bool DtoIsReturnedInArg(Type* type);
// resolve typedefs to their real type. // resolve typedefs to their real type.