changeset 1271:0686701178d3

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 .
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Mon, 27 Apr 2009 13:30:48 +0200
parents dd135ff697fa
children dd4766851b37
files gen/aa.cpp gen/arrays.cpp gen/llvmhelpers.cpp gen/llvmhelpers.h gen/statements.cpp gen/todebug.cpp gen/toir.cpp gen/toobj.cpp
diffstat 8 files changed, 58 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/gen/aa.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/aa.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -111,7 +111,8 @@
         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);
--- a/gen/arrays.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/arrays.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -978,7 +978,8 @@
 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 @@
     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);
--- a/gen/llvmhelpers.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/llvmhelpers.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -128,10 +128,9 @@
     // 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 @@
     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;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/llvmhelpers.h	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/llvmhelpers.h	Mon Apr 27 13:30:48 2009 +0200
@@ -137,6 +137,9 @@
 ///
 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
 ////////////////////////////////////////////
--- a/gen/statements.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/statements.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -1466,7 +1466,8 @@
     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);
--- a/gen/todebug.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/todebug.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -476,13 +476,13 @@
     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 @@
     }
 
     // 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 @@
     // 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;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/toir.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/toir.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -1165,17 +1165,8 @@
     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 @@
     }
 
     // anything we're not yet handling ?
-    assert(0);
+    assert(0 && "no var in ThisExp");
     return 0;
 }
 
@@ -1753,8 +1744,24 @@
         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;
 
--- a/gen/toobj.cpp	Mon Apr 27 03:40:40 2009 +0200
+++ b/gen/toobj.cpp	Mon Apr 27 13:30:48 2009 +0200
@@ -99,12 +99,6 @@
 
     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);