Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/Concurrency/Keywords.cc	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -66,5 +66,6 @@
 			bool needs_main, AggregateDecl::Aggregate cast_target ) :
 		  type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
-		  context_error( context_error ), vtable_name( getVTableName( exception_name ) ),
+		  context_error( context_error ), exception_name( exception_name ),
+		  vtable_name( getVTableName( exception_name ) ),
 		  needs_main( needs_main ), cast_target( cast_target ) {}
 
@@ -89,4 +90,5 @@
 		const std::string getter_name;
 		const std::string context_error;
+		const std::string exception_name;
 		const std::string vtable_name;
 		bool needs_main;
@@ -95,4 +97,5 @@
 		StructDecl   * type_decl = nullptr;
 		FunctionDecl * dtor_decl = nullptr;
+		StructDecl * except_decl = nullptr;
 		StructDecl * vtable_decl = nullptr;
 	};
@@ -376,4 +379,7 @@
 		else if ( is_target(decl) ) {
 			handle( decl );
+		}
+		else if ( !except_decl && exception_name == decl->name && decl->body ) {
+			except_decl = decl;
 		}
 		else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
@@ -398,7 +404,11 @@
 			assert( struct_type );
 
-			declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, {
-				new TypeExpr( struct_type->clone() ),
-			}, struct_type, nullptr ) );
+			std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
+			ObjectDecl * vtable_object = Virtual::makeVtableInstance(
+				vtable_decl->makeInst( poly_args ), struct_type, nullptr );
+			declsToAddAfter.push_back( vtable_object );
+			declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
+				vtable_object, except_decl->makeInst( std::move( poly_args ) )
+			) );
 		}
 
@@ -434,7 +444,13 @@
 	void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
 		if ( vtable_decl ) {
-			declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl, {
+			std::list< Expression * > poly_args = {
 				new TypeExpr( new StructInstType( noQualifiers, decl ) ),
-			} ) );
+			};
+			declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
+				vtable_decl->makeInst( poly_args ),
+				except_decl->makeInst( poly_args )
+			) );
+			declsToAddBefore.push_back( Virtual::makeVtableForward(
+				vtable_decl->makeInst( move( poly_args ) ) ) );
 		// Its only an error if we want a vtable and don't have one.
 		} else if ( ! vtable_name.empty() ) {
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/InitTweak/FixGlobalInit.cc	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -112,4 +112,20 @@
 			} // if
 			if ( Statement * ctor = ctorInit->ctor ) {
+				// Translation 1: Add this attribute on the global declaration:
+				//    __attribute__((section (".data#")))
+				// which makes gcc put the global in the data section,
+				// so that the global is writeable (via a const cast) in the init function.
+				// The trailing # is an injected assembly comment, to suppress the "a" in
+				//    .section .data,"a"
+				//    .section .data#,"a"
+				// to avoid assembler warning "ignoring changed section attributes for .data"
+				Type *strLitT = new PointerType( Type::Qualifiers( ),
+					new BasicType( Type::Qualifiers( ), BasicType::Char ) );
+				std::list< Expression * > attr_params;
+				attr_params.push_back( 
+					new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );
+				objDecl->attributes.push_back(new Attribute("section", attr_params));
+				// Translation 2: Move the initizliation off the global declaration,
+				// into the startup function.
 				initStatements.push_back( ctor );
 				objDecl->init = nullptr;
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -277,5 +277,12 @@
 			const DeclarationWithType * candidate = cdata.id;
 
-			// build independent unification context for candidate
+			// ignore deleted candidates.
+			// NOTE: this behavior is different from main resolver.
+			// further investigations might be needed to determine
+			// if we should implement the same rule here
+			// (i.e. error if unique best match is deleted)
+			if (candidate->isDeleted) continue;
+
+			// build independent unification context. for candidate
 			AssertionSet have, newNeed;
 			TypeEnvironment newEnv{ resn.alt.env };
Index: src/ResolvExpr/SatisfyAssertions.cpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.cpp	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/ResolvExpr/SatisfyAssertions.cpp	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -170,4 +170,11 @@
 			const ast::DeclWithType * candidate = cdata.id;
 
+			// ignore deleted candidates.
+			// NOTE: this behavior is different from main resolver.
+			// further investigations might be needed to determine
+			// if we should implement the same rule here
+			// (i.e. error if unique best match is deleted)
+			if (candidate->isDeleted) continue;
+
 			// build independent unification context for candidate
 			ast::AssertionSet have, newNeed;
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/SymTab/Autogen.cc	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -339,5 +339,10 @@
 		} catch ( SemanticErrorException & ) {
 			// okay if decl does not resolve - that means the function should not be generated
-			delete dcl;
+			// delete dcl;
+			delete dcl->statements;
+			dcl->statements = nullptr;
+			dcl->isDeleted = true;
+			definitions.push_back( dcl );
+			indexer.addId( dcl );
 		}
 	}
Index: src/SynTree/AggregateDecl.cc
===================================================================
--- src/SynTree/AggregateDecl.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/SynTree/AggregateDecl.cc	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -21,4 +21,5 @@
 #include "Common/utility.h"      // for printAll, cloneAll, deleteAll
 #include "Declaration.h"         // for AggregateDecl, TypeDecl, Declaration
+#include "Expression.h"
 #include "Initializer.h"
 #include "LinkageSpec.h"         // for Spec, linkageName, Cforall
@@ -88,4 +89,17 @@
 const char * StructDecl::typeString() const { return aggrString( kind ); }
 
+StructInstType * StructDecl::makeInst( std::list< Expression * > const & new_parameters ) {
+	std::list< Expression * > copy_parameters;
+	cloneAll( new_parameters, copy_parameters );
+	return makeInst( move( copy( copy_parameters ) ) );
+}
+
+StructInstType * StructDecl::makeInst( std::list< Expression * > && new_parameters ) {
+	assert( parameters.size() == new_parameters.size() );
+	StructInstType * type = new StructInstType( noQualifiers, this );
+	type->parameters = std::move( new_parameters );
+	return type;
+}
+
 const char * UnionDecl::typeString() const { return aggrString( Union ); }
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/SynTree/Declaration.h	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -306,4 +306,8 @@
 	bool is_thread   () { return kind == Thread   ; }
 
+	// Make a type instance of this declaration.
+	StructInstType * makeInst( std::list< Expression * > const & parameters );
+	StructInstType * makeInst( std::list< Expression * > && parameters );
+
 	virtual StructDecl * clone() const override { return new StructDecl( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
Index: src/Virtual/Tables.cc
===================================================================
--- src/Virtual/Tables.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/Virtual/Tables.cc	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -14,6 +14,8 @@
 //
 
+#include <SynTree/Attribute.h>
 #include <SynTree/Declaration.h>
 #include <SynTree/Expression.h>
+#include <SynTree/Statement.h>
 #include <SynTree/Type.h>
 
@@ -38,14 +40,4 @@
 }
 
-// Fuse base polymorphic declaration and forall arguments into a new type.
-static StructInstType * vtableInstType(
-		StructDecl * polyDecl, std::list< Expression * > && parameters ) {
-	assert( parameters.size() == polyDecl->parameters.size() );
-	StructInstType * type = new StructInstType(
-			Type::Qualifiers( /* Type::Const */ ), polyDecl );
-	type->parameters = std::move( parameters );
-	return type;
-}
-
 static ObjectDecl * makeVtableDeclaration(
 		StructInstType * type, Initializer * init ) {
@@ -66,14 +58,12 @@
 
 ObjectDecl * makeVtableForward( StructInstType * type ) {
+	assert( type );
 	return makeVtableDeclaration( type, nullptr );
 }
 
-ObjectDecl * makeVtableForward(
-		StructDecl * polyDecl, std::list< Expression * > && parameters ) {
-	return makeVtableForward( vtableInstType( polyDecl, std::move( parameters ) ) );
-}
-
 ObjectDecl * makeVtableInstance(
-		StructInstType * vtableType, Type * vobject_type, Initializer * init ) {
+		StructInstType * vtableType, Type * objectType, Initializer * init ) {
+	assert( vtableType );
+	assert( objectType );
 	StructDecl * vtableStruct = vtableType->baseStruct;
 	// Build the initialization
@@ -92,7 +82,7 @@
 						new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
 			} else if ( std::string( "size" ) == field->name ) {
-				inits.push_back( new SingleInit( new SizeofExpr( vobject_type->clone() ) ) );
+				inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
 			} else if ( std::string( "align" ) == field->name ) {
-				inits.push_back( new SingleInit( new AlignofExpr( vobject_type->clone() ) ) );
+				inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );
 			} else {
 				inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
@@ -108,9 +98,51 @@
 }
 
-ObjectDecl * makeVtableInstance(
-		StructDecl * polyDecl, std::list< Expression * > && parameters,
-		Type * vobject, Initializer * init ) {
-	return makeVtableInstance(
-		vtableInstType( polyDecl, std::move( parameters ) ), vobject, init );
+namespace {
+	std::string const functionName = "get_exception_vtable";
+}
+
+FunctionDecl * makeGetExceptionForward(
+		Type * vtableType, Type * exceptType ) {
+	assert( vtableType );
+	assert( exceptType );
+	FunctionType * type = new FunctionType( noQualifiers, false );
+	vtableType->tq.is_const = true;
+	type->returnVals.push_back( new ObjectDecl(
+		"_retvalue",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new ReferenceType( noQualifiers, vtableType ),
+		nullptr,
+        { new Attribute("unused") }
+	) );
+	type->parameters.push_back( new ObjectDecl(
+		"__unused",
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		nullptr,
+		new PointerType( noQualifiers, exceptType ),
+		nullptr,
+		{ new Attribute("unused") }
+	) );
+	return new FunctionDecl(
+		functionName,
+		noStorageClasses,
+		LinkageSpec::Cforall,
+		type,
+		nullptr
+	);
+}
+
+FunctionDecl * makeGetExceptionFunction(
+		ObjectDecl * vtableInstance, Type * exceptType ) {
+	assert( vtableInstance );
+	assert( exceptType );
+	FunctionDecl * func = makeGetExceptionForward(
+		vtableInstance->type->clone(), exceptType );
+	func->statements = new CompoundStmt( {
+		new ReturnStmt( new VariableExpr( vtableInstance ) ),
+	} );
+	return func;
 }
 
Index: src/Virtual/Tables.h
===================================================================
--- src/Virtual/Tables.h	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/Virtual/Tables.h	(revision 2494720922ef67d86a538744e2f79359a6b63e84)
@@ -27,25 +27,25 @@
 bool isVTableInstanceName( std::string const & name );
 
-/// Converts exceptions into regular structures.
-//void ( std::list< Declaration * > & translationUnit );
-
-ObjectDecl * makeVtableForward( StructInstType * );
-ObjectDecl * makeVtableForward( StructDecl *, std::list< Expression * > && );
-/* Create a forward definition of a vtable of the given type.
- *
- * Instead of the virtual table type you may provide the declaration and all
- * the forall parameters.
+ObjectDecl * makeVtableForward( StructInstType * vtableType );
+/* Create a forward declaration of a vtable of the given type.
+ * vtableType node is consumed.
  */
 
-ObjectDecl * makeVtableInstance( StructInstType *, Type *, Initializer * );
-ObjectDecl * makeVtableInstance(
-	StructDecl *, std::list< Expression * > &&, Type *, Initializer * );
+ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType,
+	Initializer * init = nullptr );
 /* Create an initialized definition of a vtable.
- *
- * The parameters are the virtual table type (or the base declaration and the
- * forall parameters), the object type and optionally an initializer.
- *
- * Instead of the virtual table type you may provide the declaration and all
- * the forall parameters.
+ * vtableType and init (if provided) nodes are consumed.
+ */
+
+// Some special code for how exceptions interact with virtual tables.
+FunctionDecl * makeGetExceptionForward( Type * vtableType, Type * exceptType );
+/* Create a forward declaration of the exception virtual function
+ * linking the vtableType to the exceptType. Both nodes are consumed.
+ */
+
+FunctionDecl * makeGetExceptionFunction(
+	ObjectDecl * vtableInstance, Type * exceptType );
+/* Create the definition of the exception virtual function.
+ * exceptType node is consumed.
  */
 
