Moved special casing of 'assert(this, "null this");' generated statements from !ThisExp into !AssertExp.

Fixed filenames for array bounds errors and probably others, fixes #271 .
This commit is contained in:
Tomas Lindquist Olsen
2009-04-27 13:30:48 +02:00
parent ba38e15f0d
commit 95b94935ee
8 changed files with 58 additions and 35 deletions

View File

@@ -111,7 +111,8 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue)
std::vector<LLValue*> args;
// file param
args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName));
IrModule* irmod = getIrModule(NULL);
args.push_back(DtoLoad(irmod->fileName));
// line param
LLConstant* c = DtoConstUint(loc.linnum);

View File

@@ -978,7 +978,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
{
Type* arrty = arr->getType()->toBasetype();
assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays");
assert((arrty->ty == Tsarray || arrty->ty == Tarray) &&
"Can only array bounds check for static or dynamic arrays");
// static arrays could get static checks for static indices
// but shouldn't since it might be generic code that's never executed
@@ -1000,7 +1001,10 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice)
std::vector<LLValue*> args;
// file param
args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName));
// get the filename from the function symbol instead of the current module
// it's wrong for instantiations of imported templates. Fixes LDC bug #271
Module* funcmodule = gIR->func()->decl->getModule();
args.push_back(DtoLoad(getIrModule(NULL)->fileName));
// line param
LLConstant* c = DtoConstUint(loc.linnum);

View File

@@ -128,10 +128,9 @@ void DtoAssert(Module* M, Loc loc, DValue* msg)
// file param
// we might be generating for an imported template function
if (!M->ir.irModule)
M->ir.irModule = new IrModule(M, M->srcfile->toChars());
IrModule* irmod = getIrModule(M);
args.push_back(DtoLoad(M->ir.irModule->fileName));
args.push_back(DtoLoad(irmod->fileName));
// line param
LLConstant* c = DtoConstUint(loc.linnum);
@@ -1399,3 +1398,17 @@ bool hasUnalignedFields(Type* t)
ts->unaligned = 1;
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////
IrModule * getIrModule(Module * M)
{
if (M == NULL)
M = gIR->func()->decl->getModule();
assert(M && "null module");
if (!M->ir.irModule)
M->ir.irModule = new IrModule(M, M->srcfile->toChars());
return M->ir.irModule;
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -137,6 +137,9 @@ bool hasUnalignedFields(Type* t);
///
DValue* DtoInlineAsmExpr(Loc loc, FuncDeclaration* fd, Expressions* arguments);
/// Create the IrModule if necessary and returns it.
IrModule* getIrModule(Module* M);
////////////////////////////////////////////
// gen/tocall.cpp stuff below
////////////////////////////////////////////

View File

@@ -1466,7 +1466,8 @@ void SwitchErrorStatement::toIR(IRState* p)
std::vector<LLValue*> args;
// file param
args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName));
IrModule* irmod = getIrModule(NULL);
args.push_back(DtoLoad(irmod->fileName));
// line param
LLConstant* c = DtoConstUint(loc.linnum);

View File

@@ -476,13 +476,13 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
LOG_SCOPE;
// we might be generating for an import
if (!m->ir.irModule)
m->ir.irModule = new IrModule(m, m->srcfile->toChars());
else if (!m->ir.irModule->diCompileUnit.isNull())
IrModule* irmod = getIrModule(m);
if (!irmod->diCompileUnit.isNull())
{
assert (m->ir.irModule->diCompileUnit.getGV()->getParent() == gIR->module
assert (irmod->diCompileUnit.getGV()->getParent() == gIR->module
&& "debug info compile unit belongs to incorrect llvm module!");
return m->ir.irModule->diCompileUnit;
return irmod->diCompileUnit;
}
// prepare srcpath
@@ -496,7 +496,7 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
}
// make compile unit
m->ir.irModule->diCompileUnit = gIR->difactory.CreateCompileUnit(
irmod->diCompileUnit = gIR->difactory.CreateCompileUnit(
global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D,
m->srcfile->name->toChars(),
srcpath,
@@ -509,10 +509,10 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
// if the linkage stays internal, we can't llvm-link the generated modules together:
// llvm's DwarfWriter uses path and filename to determine the symbol name and we'd
// end up with duplicate symbols
m->ir.irModule->diCompileUnit.getGV()->setLinkage(DEBUGINFO_LINKONCE_LINKAGE_TYPE);
m->ir.irModule->diCompileUnit.getGV()->setName(std::string("llvm.dbg.compile_unit_") + srcpath + m->srcfile->name->toChars());
irmod->diCompileUnit.getGV()->setLinkage(DEBUGINFO_LINKONCE_LINKAGE_TYPE);
irmod->diCompileUnit.getGV()->setName(std::string("llvm.dbg.compile_unit_") + srcpath + m->srcfile->name->toChars());
return m->ir.irModule->diCompileUnit;
return irmod->diCompileUnit;
}
//////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -1165,17 +1165,8 @@ DValue* ThisExp::toElem(IRState* p)
Logger::print("ThisExp::toElem: %s @ %s\n", toChars(), type->toChars());
LOG_SCOPE;
// this seems to happen for dmd generated assert statements like:
// assert(this, "null this");
// FIXME: check for TOKthis in AssertExp instead
if (!var)
{
LLValue* v = p->func()->thisArg;
assert(v);
return new DVarValue(type, v);
}
// regular this expr
else if (VarDeclaration* vd = var->isVarDeclaration()) {
if (VarDeclaration* vd = var->isVarDeclaration()) {
LLValue* v;
if (vd->toParent2() != p->func()->decl) {
Logger::println("nested this exp");
@@ -1189,7 +1180,7 @@ DValue* ThisExp::toElem(IRState* p)
}
// anything we're not yet handling ?
assert(0);
assert(0 && "no var in ThisExp");
return 0;
}
@@ -1753,8 +1744,24 @@ DValue* AssertExp::toElem(IRState* p)
return NULL;
// condition
DValue* cond = e1->toElem(p);
Type* condty = e1->type->toBasetype();
DValue* cond;
Type* condty;
// special case assert(this);
if (e1->op == TOKthis)
{
LLValue* thisarg = p->func()->thisArg;
assert(thisarg && "null thisarg, but we're in assert(this) exp;");
LLValue* thisptr = DtoLoad(p->func()->thisArg);
LLValue* thisnotnull = p->ir->CreateIsNotNull(thisptr);
cond = new DImValue(Type::tbool, thisnotnull);
condty = Type::tbool;
}
else
{
cond = e1->toElem(p);
condty = e1->type->toBasetype();
}
InvariantDeclaration* invdecl;

View File

@@ -99,12 +99,6 @@ llvm::Module* Module::genLLVMModule(Ir* sir)
sir->setState(&ir);
// module ir state
// might already exist via import, just overwrite since
// the global created for the filename must belong to the right llvm module
// FIXME: but shouldn't this always get reset between modules? like other IrSymbols
this->ir.irModule = new IrModule(this, srcfile->toChars());
// set target triple
ir.module->setTargetTriple(global.params.targetTriple);