[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
type = Type::tptrdiff_t;
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->type = Type::tptrdiff_t;
return e;

View file

@ -34,21 +34,16 @@ const LLStructType* DtoArrayType(const LLType* t)
const LLArrayType* DtoStaticArrayType(Type* t)
{
if (t->ir.type)
return isaArray(t->ir.type->get());
t = t->toBasetype();
assert(t->ty == Tsarray);
assert(t->next);
const LLType* at = DtoType(t->next);
TypeSArray* tsa = (TypeSArray*)t;
assert(tsa->dim->type->isintegral());
const LLArrayType* arrty = LLArrayType::get(at,tsa->dim->toUInteger());
Type* tnext = tsa->next;
assert(!tsa->ir.type);
tsa->ir.type = new LLPATypeHolder(arrty);
return arrty;
const LLType* elemty = DtoType(tnext);
if (elemty == LLType::VoidTy)
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) {
Logger::cout() << "to array" << '\n';
const LLType* ptrty = DtoType(totype->next);
if (ptrty == LLType::VoidTy)
ptrty = LLType::Int8Ty;
ptrty = getPtrToType(ptrty);
const LLType* ety = DtoType(fromtype->next);
if (ety == LLType::VoidTy)
ety = LLType::Int8Ty;
const LLType* ptrty = DtoArrayType(totype)->getContainedType(1);
const LLType* ety = DtoTypeNotVoid(fromtype->next);
if (DSliceValue* usl = u->isSlice()) {
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)
{
#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;
// if no destructor emit a null
@ -1384,7 +1344,6 @@ static LLConstant* build_class_dtor(ClassDeclaration* cd)
DtoForceDeclareDsymbol(dtor);
return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
#endif
}
static unsigned build_classinfo_flags(ClassDeclaration* cd)
@ -1556,7 +1515,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
if (cd->inv) {
DtoForceDeclareDsymbol(cd->inv);
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 {
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
// would be nice to figure out how to assert that this is correct
llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
if (lastbb->empty()) {
if (lastbb->empty())
{
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

View file

@ -1210,7 +1210,9 @@ LLConstant* DtoConstFieldInitializer(Type* t, 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");
assert(ex->exp);

View file

@ -73,12 +73,13 @@ DValue* DeclarationExp::toElem(IRState* p)
else {
// allocate storage on the stack
const LLType* lltype = DtoType(vd->type);
llvm::Value* allocainst;
if(gTargetData->getTypeSizeInBits(lltype) == 0)
{
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());
fatal();
}
llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
else
allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
//allocainst->setAlignment(vd->type->alignsize()); // TODO
assert(!vd->ir.irLocal);
vd->ir.irLocal = new IrLocal(vd);
@ -428,9 +429,7 @@ DValue* StringExp::toElem(IRState* p)
Type* dtype = DtoDType(type);
Type* cty = DtoDType(dtype->next);
const LLType* ct = DtoType(cty);
if (ct == LLType::VoidTy)
ct = LLType::Int8Ty;
const LLType* ct = DtoTypeNotVoid(cty);
//printf("ct = %s\n", type->next->toChars());
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());
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;
v = p->func()->decl->ir.irFunc->thisVar;
if (llvm::isa<llvm::AllocaInst>(v))
@ -1495,6 +1503,7 @@ DValue* ThisExp::toElem(IRState* p)
return new DThisValue(vd, v);
}
// anything we're not yet handling ?
assert(0);
return 0;
}
@ -2005,7 +2014,7 @@ DValue* ArrayLengthExp::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;
// condition

View file

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

View file

@ -11,7 +11,14 @@
// D->LLVM type handling stuff
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);
// returns if the type should be returned in a hidden pointer arguement
bool DtoIsReturnedInArg(Type* type);
// resolve typedefs to their real type.