diff ir/irlandingpad.cpp @ 745:5761d7e6f628

Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues (see bug #104), but a separate helper that doesn't initialize would be nicer.
author Christian Kamm <kamm incasoftware de>
date Sat, 01 Nov 2008 16:48:17 +0100
parents d97b017a8aef
children f04dde6e882c
line wrap: on
line diff
--- a/ir/irlandingpad.cpp	Sat Nov 01 14:41:57 2008 +0100
+++ b/ir/irlandingpad.cpp	Sat Nov 01 16:48:17 2008 +0100
@@ -15,10 +15,23 @@
 
     // assign storage to catch var
     if(catchstmt->var) {
-        assert(!catchstmt->var->ir.irLocal);
-        catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
-        LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage();
-        catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
+        // use the same storage for all exceptions that are not accessed in
+        // nested functions
+        if(!catchstmt->var->nestedref) {
+            assert(!catchstmt->var->ir.irLocal);
+            catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
+            LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage();
+            catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
+        }
+
+        // this will alloca if we haven't already and take care of nested refs
+        DtoDeclarationExp(catchstmt->var);
+
+        // the exception will only be stored in catch_var. copy it over if necessary
+        if(catchstmt->var->ir.irLocal->value != gIR->func()->landingPad.getExceptionStorage()) {
+            LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->landingPad.getExceptionStorage()), DtoType(catchstmt->var->type));
+            DtoStore(exc, catchstmt->var->ir.irLocal->value);
+        }
     }
 
     // emit handler, if there is one