diff gen/toir.cpp @ 209:c4c9b4ac021b trunk

[svn r225] Fixed: delete expressions no longer use llvm's free instruction, which crashes on a GC provided pointer.
author lindquist
date Wed, 14 May 2008 01:22:40 +0200
parents e0b6040585b4
children 1d6cfdbc97f0
line wrap: on
line diff
--- a/gen/toir.cpp	Tue May 13 21:41:25 2008 +0200
+++ b/gen/toir.cpp	Wed May 14 01:22:40 2008 +0200
@@ -1984,66 +1984,6 @@
         return new DImValue(type, mem, false);
     }
 
-    /*
-
-    const llvm::Type* t = DtoType(ntype);
-
-    llvm::Value* emem = 0;
-    bool inplace = false;
-
-    if (ntype->ty == Tarray) {
-        assert(arguments);
-        if (arguments->dim == 1) {
-            DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
-            llvm::Value* dimval = sz->getRVal();
-            Type* nnt = DtoDType(ntype->next);
-            if (nnt->ty == Tvoid)
-                nnt = Type::tint8;
-
-            if (p->topexp() && p->topexp()->e2 == this) {
-                assert(p->topexp()->v);
-                emem = p->topexp()->v->getLVal();
-                DtoNewDynArray(emem, dimval, nnt);
-                inplace = true;
-            }
-            else {
-                const llvm::Type* restype = DtoType(type);
-                Logger::cout() << "restype = " << *restype << '\n';
-                emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
-                DtoNewDynArray(emem, dimval, nnt);
-                return new DVarValue(newtype, emem, true);
-            }
-        }
-        else {
-            assert(0 && "num args to 'new' != 1");
-        }
-    }
-    // simple new of a single non-class, non-array value
-    else {
-        // get runtime function
-        llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
-        // get type info
-        llvm::Constant* ti = DtoTypeInfoOf(newtype);
-        assert(isaPointer(ti));
-        // call runtime
-        llvm::SmallVector<llvm::Value*,1> arg;
-        arg.push_back(ti);
-        emem = p->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem");
-    }
-
-    if (ntype->ty == Tstruct) {
-        TypeStruct* ts = (TypeStruct*)ntype;
-        if (ts->isZeroInit()) {
-            DtoStructZeroInit(emem);
-        }
-        else {
-            assert(ts->sym);
-            DtoStructCopy(emem,ts->sym->ir.irStruct->init);
-        }
-    }
-
-    return new DImValue(type, emem, inplace);
-    */
     assert(0);
 }
 
@@ -2054,55 +1994,54 @@
     Logger::print("DeleteExp::toElem: %s | %s\n", toChars(), type->toChars());
     LOG_SCOPE;
 
-    //assert(e1->type->ty != Tclass);
-
-    DValue* v = e1->toElem(p);
-    const llvm::Type* t = DtoType(v->getType());
-    llvm::Value* ldval = 0;
-    llvm::Constant* z = llvm::Constant::getNullValue(t);
-
-    Type* e1type = DtoDType(e1->type);
-
-    if (e1type->ty == Tpointer) {
-        llvm::Value* val = v->getRVal();
-        Logger::cout() << *z << '\n';
-        Logger::cout() << *val << '\n';
-        new llvm::FreeInst(val, p->scopebb());
-        new llvm::StoreInst(z, v->getLVal(), p->scopebb());
+    DValue* dval = e1->toElem(p);
+    Type* et = DtoDType(e1->type);
+
+    // simple pointer
+    if (et->ty == Tpointer)
+    {
+        llvm::Value* rval = dval->getRVal();
+        DtoDeleteMemory(rval);
+        if (dval->isVar() && dval->isVar()->lval)
+            DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal());
     }
-    else if (e1type->ty == Tclass) {
-        TypeClass* tc = (TypeClass*)e1type;
-        llvm::Value* val = 0;
-        if (tc->sym->dtors.dim > 0) {
-            val = v->getRVal();
-            DtoCallClassDtors(tc, val);
-        }
-
-        if (DVarValue* vv = v->isVar()) {
-            if (vv->var && !vv->var->onstack) {
-                if (!val) val = v->getRVal();
-                new llvm::FreeInst(val, p->scopebb());
+    // class
+    else if (et->ty == Tclass)
+    {
+        bool onstack = false;
+        if (DVarValue* vv = dval->isVar()) {
+            if (vv->var && vv->var->onstack) {
+                TypeClass* tc = (TypeClass*)et;
+                if (tc->sym->dtors.dim > 0) {
+                    DtoFinalizeClass(dval->getRVal());
+                    onstack = true;
+                }
             }
         }
-        if (!v->isThis())
-            new llvm::StoreInst(z, v->getLVal(), p->scopebb());
+        if (!onstack) {
+            llvm::Value* rval = dval->getRVal();
+            DtoDeleteClass(rval);
+        }
+        if (dval->isVar() && dval->isVar()->lval) {
+            llvm::Value* lval = dval->getLVal();
+            DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval);
+        }
     }
-    else if (e1type->ty == Tarray) {
-        // must be on the heap (correct?)
-        llvm::Value* val = v->getRVal();
-        llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
-        llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
-        llvm::Value* ptr = DtoGEP(val,zero,one,"tmp",p->scopebb());
-        ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb());
-        new llvm::FreeInst(ptr, p->scopebb());
-        DtoSetArrayToNull(val);
+    // dyn array
+    else if (et->ty == Tarray)
+    {
+        DtoDeleteArray(dval);
+        if (!dval->isSlice())
+            DtoSetArrayToNull(dval->getRVal());
     }
-    else {
-        assert(0);
+    // unknown/invalid
+    else
+    {
+        assert(0 && "invalid delete");
     }
 
-    // this expression produces no useful data
-    return 0;
+    // no value to return
+    return NULL;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////