Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ Jenkinsfile	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -392,5 +392,5 @@
 			break
 			case 'clang':
-				this.Compiler = new CC_Desc('clang', 'clang++-6.0', 'gcc-6', '-flto=thin -flto-jobs=0')
+				this.Compiler = new CC_Desc('clang', 'clang++-10', 'gcc-9', '-flto=thin -flto-jobs=0')
 			break
 			default :
Index: benchmark/Makefile.am
===================================================================
--- benchmark/Makefile.am	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ benchmark/Makefile.am	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -146,5 +146,5 @@
 
 cleancsv:
-	rm -f compile.csv basic.csv ctxswitch.csv mutex.csv scheduling.csv
+	rm -f compile.csv basic.csv ctxswitch.csv mutex.csv schedint.csv
 
 jenkins$(EXEEXT): cleancsv
@@ -157,6 +157,6 @@
 	+make mutex.csv
 	-+make mutex.diff.csv
-	+make scheduling.csv
-	-+make scheduling.diff.csv
+	+make schedint.csv
+	-+make schedint.diff.csv
 @DOifskipcompile@
 	cat compile.csv
@@ -167,6 +167,6 @@
 	cat mutex.csv
 	-cat mutex.diff.csv
-	cat scheduling.csv
-	-cat scheduling.diff.csv
+	cat schedint.csv
+	-cat schedint.diff.csv
 
 compile.csv:
@@ -198,5 +198,5 @@
 	$(srcdir)/fixcsv.sh $@
 
-scheduling.csv:
+schedint.csv:
 	echo "building $@"
 	echo "schedint-1,schedint-2,schedext-1,schedext-2" > $@
@@ -490,29 +490,29 @@
 
 compile-array$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/array.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/array.cfa
 
 compile-attributes$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/attributes.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/attributes.cfa
 
 compile-empty$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(srcdir)/compile/empty.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(srcdir)/compile/empty.cfa
 
 compile-expression$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/expression.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/expression.cfa
 
 compile-io$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/io1.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/io1.cfa
 
 compile-monitor$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/monitor.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurrent/monitor.cfa
 
 compile-operators$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/operators.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/operators.cfa
 
 compile-thread$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/thread.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurrent/thread.cfa
 
 compile-typeof$(EXEEXT):
-	$(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
+	$(CFACOMPILE) -DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/typeof.cfa
 
 ## =========================================================================================================
Index: doc/proposals/ZeroCostPreemption.md
===================================================================
--- doc/proposals/ZeroCostPreemption.md	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
+++ doc/proposals/ZeroCostPreemption.md	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -0,0 +1,16 @@
+## "Zero Cost" Preemption in for Cforall ##
+
+Similar to "Zero Cost" exceptions, this is a proposal to support preemption with little to no runtime cost for the book-keeping. (Other than having exceptions).
+
+Preemption stops users threads at random locations and forces a context switch using a signal handler. Since this is not safe and/or does not make sense in many contexts, the runtime needs a system to disable interrupts for certain regions of codes.
+
+Currently, Cforall uses _[kernel] thread-local storage_(TLS) to handle this, setting a flag to false when preemption should be disabled. This works on x86/x64 but only with a specific TLS model, and does not work with ARM. The problem is that if the loading of the TLS variable is not done in a single instruction, it allows a race condition, where user-threads could disable preemption for the wrong processor, i.e., be moved to a different processor and update the previous processor.
+
+The fix being worked on is to protect the specific TLS variable with a special function.
+
+## The Proposal ##
+A better approach, would be to re-use the Exception Handling Data structure to identify regions of code that do not allow preemption. These regions of code would be marked using the same mechanism which marks stack unwinding requirements.
+
+When the signal handler is called, it would search the stack similarly to how the stack is searched when an exception is thrown and do the context switch or not based on the result.
+
+This is an optimization, since signal handlers for preemption are already rare and costly but enabling/disabling interrupts is very common (1000x more common). Using the "Zero-Cost" exception mechanism, enabling/disabling interrupts should be free at runtime and the rare signal/handler become more expensive.
Index: libcfa/src/bits/containers.hfa
===================================================================
--- libcfa/src/bits/containers.hfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/bits/containers.hfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -157,4 +157,15 @@
 			tail = &get_next( *val );
 			*tail = 1p;
+		}
+
+		T * peek( __queue(T) & this ) {
+			verify(*this.tail == 1p);
+			T * head = this.head;
+			if( head != 1p ) {
+				verify(*this.tail == 1p);
+				return head;
+			}
+			verify(*this.tail == 1p);
+			return 0p;
 		}
 
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -47,6 +47,5 @@
 
 //-----------------------------------------------------------------------------
-FORALL_DATA_INSTANCE(CoroutineCancelled,
-		(dtype coroutine_t | sized(coroutine_t)), (coroutine_t))
+FORALL_DATA_INSTANCE(CoroutineCancelled, (dtype coroutine_t), (coroutine_t))
 
 struct __cfaehm_node {
@@ -59,5 +58,5 @@
 void mark_exception(CoroutineCancelled(T) *) {}
 
-forall(dtype T | sized(T))
+forall(dtype T)
 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
 	dst->the_coroutine = src->the_coroutine;
@@ -77,5 +76,7 @@
 	exception_t * except = (exception_t *)(1 + (__cfaehm_node *)desc->cancellation);
 
+	// TODO: Remove explitate vtable set once trac#186 is fixed.
 	CoroutineCancelled(T) except;
+	except.virtual_table = &get_exception_vtable(&except);
 	except.the_coroutine = &cor;
 	except.the_exception = except;
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -22,7 +22,5 @@
 //-----------------------------------------------------------------------------
 // Exception thrown from resume when a coroutine stack is cancelled.
-// Should not have to be be sized (see trac #196).
-FORALL_DATA_EXCEPTION(CoroutineCancelled,
-		(dtype coroutine_t | sized(coroutine_t)), (coroutine_t)) (
+FORALL_DATA_EXCEPTION(CoroutineCancelled, (dtype coroutine_t), (coroutine_t)) (
 	coroutine_t * the_coroutine;
 	exception_t * the_exception;
@@ -30,7 +28,4 @@
 
 forall(dtype T)
-void mark_exception(CoroutineCancelled(T) *);
-
-forall(dtype T | sized(T))
 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src);
 
@@ -42,7 +37,5 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(dtype T | sized(T)
-		| is_resumption_exception(CoroutineCancelled(T))
-		| VTABLE_ASSERTION(CoroutineCancelled, (T))) {
+trait is_coroutine(dtype T | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
 	void main(T & this);
 	$coroutine * get_coroutine(T & this);
Index: libcfa/src/concurrency/locks.cfa
===================================================================
--- libcfa/src/concurrency/locks.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
+++ libcfa/src/concurrency/locks.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -0,0 +1,428 @@
+#include "locks.hfa"
+#include "kernel_private.hfa"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <kernel.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+///////////////////////////////////////////////////////////////////
+//// info_thread
+///////////////////////////////////////////////////////////////////
+forall(dtype L | is_blocking_lock(L)) {
+	void ?{}( info_thread(L) & this, $thread * t ) {
+		this.t = t;
+		this.lock = 0p;
+	}
+
+	void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) {
+		this.t = t;
+		this.info = info;
+		this.lock = 0p;
+	}
+
+	void ^?{}( info_thread(L) & this ){
+		// default
+	}
+
+	info_thread(L) *& get_next( info_thread(L) & this ) {
+		return this.next;
+	}
+}
+///////////////////////////////////////////////////////////////////
+//// Blocking Locks
+///////////////////////////////////////////////////////////////////
+
+void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ) {
+	this.lock{};
+	this.blocked_threads{};
+	this.wait_count = 0;
+	this.multi_acquisition = multi_acquisition;
+	this.strict_owner = strict_owner;
+	this.owner = 0p;
+	this.recursion_count = 0;
+}
+
+void ^?{}( blocking_lock & this ) {
+	// default
+}
+
+void ?{}( mutex_lock & this ) {
+	((blocking_lock &)this){ false, false };
+}
+
+void ^?{}( mutex_lock & this ) {
+	// default
+}
+
+void ?{}( owner_lock & this ) {
+	((blocking_lock &)this){ true, true };
+}
+
+void ^?{}( owner_lock & this ) {
+	// default
+}
+
+void ?{}( recursive_mutex_lock & this ) {
+	((blocking_lock &)this){ true, false };
+}
+
+void ^?{}( recursive_mutex_lock & this ) {
+	// default
+}
+
+void lock( blocking_lock & this ) with( this ) {
+	lock( lock __cfaabi_dbg_ctx2 );
+	if ( owner == kernelTLS.this_thread && !multi_acquisition) {
+		fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
+		exit(EXIT_FAILURE);
+	} else if ( owner != 0p && owner != kernelTLS.this_thread ) {
+		append( blocked_threads, kernelTLS.this_thread );
+		wait_count++;
+		unlock( lock );
+		park( __cfaabi_dbg_ctx );
+	} else if ( owner == kernelTLS.this_thread && multi_acquisition ) {
+		recursion_count++;
+		unlock( lock );
+	} else {
+		owner = kernelTLS.this_thread;
+		recursion_count = 1;
+		unlock( lock );
+	}
+}
+
+bool try_lock( blocking_lock & this ) with( this ) {
+	bool ret = false;
+	lock( lock __cfaabi_dbg_ctx2 );
+	if ( owner == 0p ) {
+		owner = kernelTLS.this_thread;
+		if ( multi_acquisition ) recursion_count = 1;
+		ret = true;
+	} else if ( owner == kernelTLS.this_thread && multi_acquisition ) {
+		recursion_count++;
+		ret = true;
+	}
+	unlock( lock );
+	return ret;
+}
+
+void unlock( blocking_lock & this ) with( this ) {
+	lock( lock __cfaabi_dbg_ctx2 );
+	if ( owner == 0p ){ // no owner implies lock isn't held
+		fprintf( stderr, "There was an attempt to release a lock that isn't held" );
+		return;
+	} else if ( strict_owner && owner != kernelTLS.this_thread ) {
+		fprintf( stderr, "A thread other than the owner attempted to release an owner lock" );
+		return;
+	}
+	recursion_count--;
+	if ( recursion_count == 0 ) {
+		$thread * thrd = pop_head( blocked_threads );
+		owner = thrd;
+		recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
+		wait_count--;
+		unpark( thrd __cfaabi_dbg_ctx2 );
+	}
+	unlock( lock );
+}
+
+size_t wait_count( blocking_lock & this ) with( this ) {
+	return wait_count;
+}
+
+
+void set_recursion_count( blocking_lock & this, size_t recursion ) with( this ) {
+	recursion_count = recursion;
+}
+
+size_t get_recursion_count( blocking_lock & this ) with( this ) {
+	return recursion_count;
+}
+
+void add_( blocking_lock & this, $thread * t ) with( this ) {
+    lock( lock __cfaabi_dbg_ctx2 );
+	if ( owner != 0p ) {
+		append( blocked_threads, t );
+		wait_count++;
+		unlock( lock );
+	} else {
+		owner = t;
+		if ( multi_acquisition ) recursion_count = 1;
+		unpark( t __cfaabi_dbg_ctx2 );
+		unlock( lock );
+	}
+}
+
+void remove_( blocking_lock & this ) with( this ) {
+    lock( lock __cfaabi_dbg_ctx2 );
+	if ( owner == 0p ){ // no owner implies lock isn't held
+		fprintf( stderr, "A lock that is not held was passed to a synchronization lock" );
+	} else if ( strict_owner && owner != kernelTLS.this_thread ) {
+		fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" );
+	} else {
+		$thread * thrd = pop_head( blocked_threads );
+		owner = thrd;
+		recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
+		wait_count--;
+		unpark( thrd __cfaabi_dbg_ctx2 );
+	}
+	unlock( lock );
+}
+
+///////////////////////////////////////////////////////////////////
+//// Overloaded routines for traits
+///////////////////////////////////////////////////////////////////
+
+// In an ideal world this may not be necessary
+// Is it possible for nominal inheritance to inherit traits??
+// If that occurs we would avoid all this extra code
+
+void lock( mutex_lock & this ){
+	lock( (blocking_lock &)this );
+}
+
+void unlock( mutex_lock & this ){
+	unlock( (blocking_lock &)this );
+}
+
+void add_( mutex_lock & this, struct $thread * t ){
+	add_( (blocking_lock &)this, t );
+}
+
+void remove_( mutex_lock & this ){
+	remove_( (blocking_lock &)this );
+}
+
+void set_recursion_count( mutex_lock & this, size_t recursion ){
+	set_recursion_count( (blocking_lock &)this, recursion );
+}
+
+size_t get_recursion_count( mutex_lock & this ){
+	get_recursion_count( (blocking_lock &)this );
+}
+
+void lock( recursive_mutex_lock & this ){
+	lock( (blocking_lock &)this );
+}
+
+void unlock( recursive_mutex_lock & this ){
+	unlock( (blocking_lock &)this );
+}
+
+void add_( recursive_mutex_lock & this, struct $thread * t ){
+	add_( (blocking_lock &)this, t );
+}
+
+void remove_( recursive_mutex_lock & this ){
+	remove_( (blocking_lock &)this );
+}
+
+void set_recursion_count( recursive_mutex_lock & this, size_t recursion ){
+	set_recursion_count( (blocking_lock &)this, recursion );
+}
+
+size_t get_recursion_count( recursive_mutex_lock & this ){
+	get_recursion_count( (blocking_lock &)this );
+}
+
+///////////////////////////////////////////////////////////////////
+//// Synchronization Locks
+///////////////////////////////////////////////////////////////////
+
+forall(dtype L | is_blocking_lock(L)) {
+	void ?{}( synchronization_lock(L) & this, bool reacquire_after_signal ){
+		this.lock{};
+		this.blocked_threads{};
+		this.count = 0;
+		this.reacquire_after_signal = reacquire_after_signal;
+	}
+
+	void ^?{}( synchronization_lock(L) & this ){
+		// default
+	}
+
+	void ?{}( condition_variable(L) & this ){
+		((synchronization_lock(L) &)this){ true };
+	}
+
+	void ^?{}( condition_variable(L) & this ){
+		// default
+	}
+
+	void ?{}( thread_queue(L) & this ){
+		((synchronization_lock(L) &)this){ false };
+	}
+
+	void ^?{}( thread_queue(L) & this ){
+		// default
+	}
+
+	bool notify_one( synchronization_lock(L) & this ) with( this ) {
+		lock( lock __cfaabi_dbg_ctx2 );
+		bool ret = !!blocked_threads;
+		info_thread(L) * popped = pop_head( blocked_threads );
+		if(popped != 0p) {
+			if( reacquire_after_signal ){
+				add_(*popped->lock, popped->t);
+			} else {
+				unpark(
+					popped->t __cfaabi_dbg_ctx2
+				);
+			}
+		}
+		unlock( lock );
+		return ret;
+	}
+
+	bool notify_all( synchronization_lock(L) & this ) with(this) {
+		lock( lock __cfaabi_dbg_ctx2 );
+		bool ret = blocked_threads ? true : false;
+		while( blocked_threads ) {
+			info_thread(L) * popped = pop_head( blocked_threads );
+			if(popped != 0p){
+				if( reacquire_after_signal ){
+					add_(*popped->lock, popped->t);
+				} else {
+					unpark(
+						popped->t __cfaabi_dbg_ctx2
+					);
+				}
+			}
+		}
+		unlock( lock );
+		return ret;
+	}
+
+	uintptr_t front( synchronization_lock(L) & this ) with(this) {
+		return (*peek(blocked_threads)).info;
+	}
+
+	bool empty( synchronization_lock(L) & this ) with(this) {
+		return blocked_threads ? false : true;
+	}
+
+	int counter( synchronization_lock(L) & this ) with(this) {
+		return count;
+	}
+
+	void queue_info_thread( synchronization_lock(L) & this, info_thread(L) & i ) with(this) {
+		lock( lock __cfaabi_dbg_ctx2 );
+		append( blocked_threads, &i );
+		count++;
+		unlock( lock );
+		park( __cfaabi_dbg_ctx );
+	}
+
+
+	void wait( synchronization_lock(L) & this ) with(this) {
+		info_thread( L ) i = { kernelTLS.this_thread };
+		queue_info_thread( this, i );
+	}
+
+	void wait( synchronization_lock(L) & this, uintptr_t info ) with(this) {
+		info_thread( L ) i = { kernelTLS.this_thread, info };
+		queue_info_thread( this, i );
+	}
+	// I still need to implement the time delay wait routines
+	bool wait( synchronization_lock(L) & this, Duration duration ) with(this) {
+		timeval tv = { time(0) };
+		Time t = { tv };
+		return wait( this, t + duration );
+	}
+
+	bool wait( synchronization_lock(L) & this, uintptr_t info, Duration duration ) with(this) {
+		// TODO: ADD INFO
+		return wait( this, duration );
+	}
+
+	bool wait( synchronization_lock(L) & this, Time time ) with(this) {
+		return false; //default
+	}
+
+	bool wait( synchronization_lock(L) & this, uintptr_t info, Time time ) with(this) {
+		// TODO: ADD INFO
+		return wait( this, time );
+	}
+
+	void queue_info_thread_unlock( synchronization_lock(L) & this, L & l, info_thread(L) & i ) with(this) {
+		lock( lock __cfaabi_dbg_ctx2 );
+		append( this.blocked_threads, &i );
+		count++;
+		i.lock = &l;
+		size_t recursion_count = get_recursion_count(l);
+		remove_( l );
+		unlock( lock );
+		park( __cfaabi_dbg_ctx ); // blocks here
+
+		set_recursion_count(l, recursion_count); // resets recursion count here after waking
+	}
+
+	void wait( synchronization_lock(L) & this, L & l ) with(this) {
+		info_thread(L) i = { kernelTLS.this_thread };
+		queue_info_thread_unlock( this, l, i );
+	}
+
+	void wait( synchronization_lock(L) & this, L & l, uintptr_t info ) with(this) {
+		info_thread(L) i = { kernelTLS.this_thread, info };
+		queue_info_thread_unlock( this, l, i );
+	}
+
+	bool wait( synchronization_lock(L) & this, L & l, Duration duration ) with(this) {
+		timeval tv = { time(0) };
+		Time t = { tv };
+		return wait( this, l, t + duration );
+	}
+
+	bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
+		// TODO: ADD INFO
+		return wait( this, l, duration );
+	}
+
+	bool wait( synchronization_lock(L) & this, L & l, Time time ) with(this) {
+		return false; //default
+	}
+
+	bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Time time ) with(this) {
+		// TODO: ADD INFO
+		return wait( this, l, time );
+	}
+}
+
+///////////////////////////////////////////////////////////////////
+//// condition lock alternative approach
+///////////////////////////////////////////////////////////////////
+
+// the solution below is less efficient but does not require the lock to have a specific add/remove routine
+
+///////////////////////////////////////////////////////////////////
+//// is_simple_lock
+///////////////////////////////////////////////////////////////////
+
+forall(dtype L | is_simple_lock(L)) {
+	void ?{}( condition_lock(L) & this ){
+		// default
+	}
+
+	void ^?{}( condition_lock(L) & this ){
+		// default
+	}
+
+	bool notify_one( condition_lock(L) & this ) with(this) {
+		return notify_one( c_var );
+	}
+
+	bool notify_all( condition_lock(L) & this ) with(this) {
+		return notify_all( c_var );
+	}
+
+	void wait( condition_lock(L) & this, L & l ) with(this) {
+		lock( m_lock );
+		size_t recursion = get_recursion_count( l );
+		unlock( l );
+		wait( c_var, m_lock );
+		lock( l );
+		set_recursion_count( l , recursion );
+		unlock( m_lock );
+	}
+}
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
+++ libcfa/src/concurrency/locks.hfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -0,0 +1,211 @@
+#include <stdbool.h>
+
+#include "bits/algorithm.hfa"
+#include "bits/locks.hfa"
+#include "bits/containers.hfa"
+
+#include "invoke.h"
+
+#include "time_t.hfa"
+#include "time.hfa"
+#include <sys/time.h>
+
+///////////////////////////////////////////////////////////////////
+//// is_blocking_lock
+///////////////////////////////////////////////////////////////////
+
+trait is_blocking_lock(dtype L | sized(L)) {
+	void add_( L &, struct $thread * );		// For synchronization locks to use when acquiring
+	void remove_( L & );    // For synchronization locks to use when releasing
+	size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
+	void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
+};
+
+///////////////////////////////////////////////////////////////////
+//// info_thread
+///////////////////////////////////////////////////////////////////
+
+forall(dtype L | is_blocking_lock(L)) {
+	struct info_thread {
+		struct $thread * t;
+		uintptr_t info;
+		info_thread(L) * next;
+		L * lock;
+	};
+
+
+	void ?{}( info_thread(L) & this, $thread * t );
+	void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
+	void ^?{}( info_thread(L) & this );
+
+	info_thread(L) *& get_next( info_thread(L) & this );
+}
+
+///////////////////////////////////////////////////////////////////
+//// Blocking Locks
+///////////////////////////////////////////////////////////////////
+struct blocking_lock {
+	// Spin lock used for mutual exclusion
+	__spinlock_t lock;
+
+	// List of blocked threads
+	__queue_t( struct $thread ) blocked_threads;
+
+	// Count of current blocked threads
+	size_t wait_count;
+
+	// Flag if the lock allows multiple acquisition
+	bool multi_acquisition;
+
+	// Flag if lock can be released by non owner
+	bool strict_owner;
+
+	// Current thread owning the lock
+	struct $thread * owner;
+
+	// Number of recursion level
+	size_t recursion_count;
+};
+
+struct mutex_lock {
+	inline blocking_lock;
+};
+
+struct owner_lock {
+	inline blocking_lock;
+};
+
+struct recursive_mutex_lock {
+	inline blocking_lock;
+};
+
+void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
+void ^?{}( blocking_lock & this );
+
+void ?{}( mutex_lock & this );
+void ^?{}( mutex_lock & this );
+
+void ?{}( owner_lock & this );
+void ^?{}( owner_lock & this );
+
+void ?{}( recursive_mutex_lock & this );
+void ^?{}( recursive_mutex_lock & this );
+
+void lock( blocking_lock & this );
+bool try_lock( blocking_lock & this );
+void unlock( blocking_lock & this );
+void add_( blocking_lock & this, struct $thread * t );
+void remove_( blocking_lock & this );
+size_t wait_count( blocking_lock & this );
+void set_recursion_count( blocking_lock & this, size_t recursion );
+size_t get_recursion_count( blocking_lock & this );
+
+void lock( mutex_lock & this );
+void unlock( mutex_lock & this );
+void add_( mutex_lock & this, struct $thread * t );
+void remove_( mutex_lock & this );
+void set_recursion_count( mutex_lock & this, size_t recursion );
+size_t get_recursion_count( mutex_lock & this );
+
+void lock( recursive_mutex_lock & this );
+void unlock( recursive_mutex_lock & this );
+void add_( recursive_mutex_lock & this, struct $thread * t );
+void remove_( recursive_mutex_lock & this );
+void set_recursion_count( recursive_mutex_lock & this, size_t recursion );
+size_t get_recursion_count( recursive_mutex_lock & this );
+
+///////////////////////////////////////////////////////////////////
+//// Synchronization Locks
+///////////////////////////////////////////////////////////////////
+forall(dtype L | is_blocking_lock(L)) {
+	struct synchronization_lock {
+		// Spin lock used for mutual exclusion
+		__spinlock_t lock;
+
+		// List of blocked threads
+		__queue_t( info_thread(L) ) blocked_threads;
+
+		// Count of current blocked threads
+		int count;
+
+		// If true threads will reacquire the lock they block on upon waking
+		bool reacquire_after_signal;
+	};
+
+	struct condition_variable {
+		inline synchronization_lock(L);
+	};
+
+	struct thread_queue {
+		inline synchronization_lock(L);
+	};
+
+
+	void ?{}( synchronization_lock(L) & this, bool multi_acquisition, bool strict_owner );
+	void ^?{}( synchronization_lock(L) & this );
+
+	void ?{}( condition_variable(L) & this );
+	void ^?{}( condition_variable(L) & this );
+
+	void ?{}( thread_queue(L) & this );
+	void ^?{}( thread_queue(L) & this );
+
+	bool notify_one( synchronization_lock(L) & this );
+	bool notify_all( synchronization_lock(L) & this );
+
+	uintptr_t front( synchronization_lock(L) & this );
+
+	bool empty( synchronization_lock(L) & this );
+	int counter( synchronization_lock(L) & this );
+
+	// wait functions that are not passed a mutex lock
+	void wait( synchronization_lock(L) & this );
+	void wait( synchronization_lock(L) & this, uintptr_t info );
+	bool wait( synchronization_lock(L) & this, Duration duration );
+	bool wait( synchronization_lock(L) & this, uintptr_t info, Duration duration );
+	bool wait( synchronization_lock(L) & this, Time time );
+	bool wait( synchronization_lock(L) & this, uintptr_t info, Time time );
+
+	// wait functions that are passed a lock
+	bool notify_one( synchronization_lock(L) & this, L & l );
+	bool notify_all( synchronization_lock(L) & this, L & l );
+
+	void wait( synchronization_lock(L) & this, L & l );
+	void wait( synchronization_lock(L) & this, L & l, uintptr_t info );
+	bool wait( synchronization_lock(L) & this, L & l, Duration duration );
+	bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Duration duration );
+	bool wait( synchronization_lock(L) & this, L & l, Time time );
+	bool wait( synchronization_lock(L) & this, L & l, uintptr_t info, Time time );
+}
+
+///////////////////////////////////////////////////////////////////
+//// condition lock alternative approach
+///////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////
+//// is_simple_lock
+///////////////////////////////////////////////////////////////////
+
+trait is_simple_lock(dtype L | sized(L)) {
+	void lock( L & );		// For synchronization locks to use when acquiring
+	void unlock( L & );    // For synchronization locks to use when releasing
+	size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
+	void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
+};
+
+forall(dtype L | is_simple_lock(L)) {
+	struct condition_lock {
+		// Spin lock used for mutual exclusion
+		mutex_lock m_lock;
+
+		condition_variable( mutex_lock ) c_var;
+	};
+
+	void ?{}( condition_lock(L) & this );
+	void ^?{}( condition_lock(L) & this );
+
+	bool notify_one( condition_lock(L) & this );
+	bool notify_all( condition_lock(L) & this );
+	void wait( condition_lock(L) & this, L & l );
+}
Index: libcfa/src/exception.h
===================================================================
--- libcfa/src/exception.h	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/exception.h	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -76,21 +76,21 @@
 // implemented in the .c file either so they all have to be inline.
 
-trait is_exception(dtype exceptT) {
+trait is_exception(dtype exceptT, dtype virtualT) {
 	/* The first field must be a pointer to a virtual table.
-	 * That virtual table must be a decendent of the base exception virtual tab$
+	 * That virtual table must be a decendent of the base exception virtual table.
 	 */
-	void mark_exception(exceptT *);
-	// This is never used and should be a no-op.
+	virtualT const & get_exception_vtable(exceptT *);
+	// Always returns the virtual table for this type (associated types hack).
 };
 
-trait is_termination_exception(dtype exceptT | is_exception(exceptT)) {
+trait is_termination_exception(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) {
 	void defaultTerminationHandler(exceptT &);
 };
 
-trait is_resumption_exception(dtype exceptT | is_exception(exceptT)) {
+trait is_resumption_exception(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) {
 	void defaultResumptionHandler(exceptT &);
 };
 
-forall(dtype exceptT | is_termination_exception(exceptT))
+forall(dtype exceptT, dtype virtualT | is_termination_exception(exceptT, virtualT))
 static inline void $throw(exceptT & except) {
 	__cfaehm_throw_terminate(
@@ -100,5 +100,5 @@
 }
 
-forall(dtype exceptT | is_resumption_exception(exceptT))
+forall(dtype exceptT, dtype virtualT | is_resumption_exception(exceptT, virtualT))
 static inline void $throwResume(exceptT & except) {
 	__cfaehm_throw_resume(
@@ -108,15 +108,15 @@
 }
 
-forall(dtype exceptT | is_exception(exceptT))
+forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT))
 static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) {
 	__cfaehm_cancel_stack( (exception_t *)&except );
 }
 
-forall(dtype exceptT | is_exception(exceptT))
+forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT))
 static inline void defaultTerminationHandler(exceptT & except) {
 	return cancel_stack( except );
 }
 
-forall(dtype exceptT | is_exception(exceptT))
+forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT))
 static inline void defaultResumptionHandler(exceptT & except) {
 	throw except;
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/exception.hfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -95,5 +95,5 @@
 // visible anywhere you use the instantiation of the exception is used.
 #define POLY_VTABLE_DECLARATION(exception_name, ...) \
-	void mark_exception(exception_name(__VA_ARGS__) *); \
+	VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable(exception_name(__VA_ARGS__) *); \
 	extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name)
 
@@ -125,4 +125,13 @@
 #define VTABLE_ASSERTION(exception_name, parameters) \
 	{ VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); }
+
+// IS_EXCEPTION(exception_name [, (...parameters)])
+// IS_RESUMPTION_EXCEPTION(exception_name [, (parameters...)])
+// IS_TERMINATION_EXCEPTION(exception_name [, (parameters...)])
+// Create an assertion that exception_name, possibly with the qualifing parameters, is the given
+// kind of exception with the standard vtable with the same parameters if applicable.
+#define IS_EXCEPTION(...) _IS_EXCEPTION(is_exception, __VA_ARGS__, , ~)
+#define IS_RESUMPTION_EXCEPTION(...) _IS_EXCEPTION(is_resumption_exception, __VA_ARGS__, , ~)
+#define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)
 
 // All internal helper macros begin with an underscore.
@@ -160,10 +169,11 @@
 
 #define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \
-	forall(_UNPACK assertions | VTABLE_ASSERTION(exception_name, parameters) ) \
+	forall(_UNPACK assertions | \
+		is_exception(exception_name parameters, VTABLE_TYPE(exception_name) parameters)) \
 	void ?{}(exception_name parameters & this)
 
 #define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \
 	_FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \
-		VTABLE_INIT(this, exception_name); \
+		(this).virtual_table = &get_exception_vtable(&this); \
 	}
 
@@ -185,6 +195,6 @@
 #define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
 	struct exception_name; \
-	void mark_exception(exception_name *); \
 	VTABLE_TYPE(exception_name); \
+	VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *); \
 	extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
 	VTABLE_TYPE(exception_name) { \
@@ -197,5 +207,7 @@
 
 #define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
-	void mark_exception(exception_name *) {} \
+	VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *) { \
+		return VTABLE_NAME(exception_name); \
+	} \
 	void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
 		*this = *other; \
@@ -218,5 +230,9 @@
 
 #define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \
-	void mark_exception(exception_name(__VA_ARGS__) *) {} \
+	extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name); \
+	VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable( \
+			exception_name(__VA_ARGS__) *) { \
+		return VTABLE_NAME(exception_name); \
+	} \
 	void _GLUE2(exception_name,_copy)( \
 			exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \
@@ -227,2 +243,5 @@
 		_GLUE2(exception_name,_copy), ^?{}, \
 		_CLOSE
+
+#define _IS_EXCEPTION(kind, exception_name, parameters, ...) \
+	kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters)
Index: libcfa/src/limits.cfa
===================================================================
--- libcfa/src/limits.cfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/limits.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 18:06:52 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Sep 30 22:56:32 2020
-// Update Count     : 76
+// Last Modified On : Thu Mar  1 16:22:51 2018
+// Update Count     : 74
 //
 
@@ -23,131 +23,131 @@
 // Integral Constants
 
-signed char MIN = SCHAR_MIN;
-unsigned char MIN = 0;
-short int MIN = SHRT_MIN;
-unsigned short int MIN = 0;
-int MIN = INT_MIN;
-unsigned int MIN = 0;
-long int MIN = LONG_MIN;
-unsigned long int MIN = 0;
-long long int MIN = LLONG_MIN;
-unsigned long long int MIN = 0;
+const signed char MIN = SCHAR_MIN;
+const unsigned char MIN = 0;
+const short int MIN = SHRT_MIN;
+const unsigned short int MIN = 0;
+const int MIN = INT_MIN;
+const unsigned int MIN = 0;
+const long int MIN = LONG_MIN;
+const unsigned long int MIN = 0;
+const long long int MIN = LLONG_MIN;
+const unsigned long long int MIN = 0;
 
-signed char MAX = SCHAR_MAX;
-unsigned char MAX = UCHAR_MAX;
-short int MAX = SHRT_MAX;
-unsigned short int MAX = USHRT_MAX;
-int MAX = INT_MAX;
-unsigned int MAX = UINT_MAX;
-long int MAX = LONG_MAX;
-unsigned long int MAX = ULONG_MAX;
-long long int MAX = LLONG_MAX;
-unsigned long long int MAX = ULLONG_MAX;
+const signed char MAX = SCHAR_MAX;
+const unsigned char MAX = UCHAR_MAX;
+const short int MAX = SHRT_MAX;
+const unsigned short int MAX = USHRT_MAX;
+const int MAX = INT_MAX;
+const unsigned int MAX = UINT_MAX;
+const long int MAX = LONG_MAX;
+const unsigned long int MAX = ULONG_MAX;
+const long long int MAX = LLONG_MAX;
+const unsigned long long int MAX = ULLONG_MAX;
 
 // Floating-Point Constants
 
-float MIN = FLT_MIN;
-double MIN = DBL_MIN;
-long double MIN = LDBL_MIN;
-float _Complex MIN = __FLT_MIN__ + __FLT_MIN__ * I;
-double _Complex MIN = DBL_MIN +  DBL_MIN * I;
-long double _Complex MIN = LDBL_MIN + LDBL_MIN * I;
+const float MIN = FLT_MIN;
+const double MIN = DBL_MIN;
+const long double MIN = LDBL_MIN;
+const float _Complex MIN = __FLT_MIN__ + __FLT_MIN__ * I;
+const double _Complex MIN = DBL_MIN +  DBL_MIN * I;
+const long double _Complex MIN = LDBL_MIN + LDBL_MIN * I;
 
-float MAX = FLT_MAX;
-double MAX = DBL_MAX;
-long double MAX = LDBL_MAX;
-float _Complex MAX = FLT_MAX + FLT_MAX * I;
-double _Complex MAX = DBL_MAX + DBL_MAX * I;
-long double _Complex MAX = LDBL_MAX + LDBL_MAX * I;
+const float MAX = FLT_MAX;
+const double MAX = DBL_MAX;
+const long double MAX = LDBL_MAX;
+const float _Complex MAX = FLT_MAX + FLT_MAX * I;
+const double _Complex MAX = DBL_MAX + DBL_MAX * I;
+const long double _Complex MAX = LDBL_MAX + LDBL_MAX * I;
 
-float PI = (float)M_PI;									// pi
-float PI_2 = (float)M_PI_2;								// pi / 2
-float PI_4 = (float)M_PI_4;								// pi / 4
-float _1_PI = (float)M_1_PI;							// 1 / pi
-float _2_PI = (float)M_2_PI;							// 2 / pi
-float _2_SQRT_PI = (float)M_2_SQRTPI;					// 2 / sqrt(pi)
+const float PI = (float)M_PI;							// pi
+const float PI_2 = (float)M_PI_2;						// pi / 2
+const float PI_4 = (float)M_PI_4;						// pi / 4
+const float _1_PI = (float)M_1_PI;						// 1 / pi
+const float _2_PI = (float)M_2_PI;						// 2 / pi
+const float _2_SQRT_PI = (float)M_2_SQRTPI;				// 2 / sqrt(pi)
 
-double PI = M_PI;										// pi
-double PI_2 = M_PI_2;									// pi / 2
-double PI_4 = M_PI_4;									// pi / 4
-double _1_PI = M_1_PI;									// 1 / pi
-double _2_PI = M_2_PI;									// 2 / pi
-double _2_SQRT_PI = M_2_SQRTPI;							// 2 / sqrt(pi)
+const double PI = M_PI;									// pi
+const double PI_2 = M_PI_2;								// pi / 2
+const double PI_4 = M_PI_4;								// pi / 4
+const double _1_PI = M_1_PI;							// 1 / pi
+const double _2_PI = M_2_PI;							// 2 / pi
+const double _2_SQRT_PI = M_2_SQRTPI;					// 2 / sqrt(pi)
 
-long double PI = M_PIl;									// pi
-long double PI_2 = M_PI_2l;								// pi / 2
-long double PI_4 = M_PI_4l;								// pi / 4
-long double _1_PI = M_1_PIl;							// 1 / pi
-long double _2_PI = M_2_PIl;							// 2 / pi
-long double _2_SQRT_PI = M_2_SQRTPIl;					// 2 / sqrt(pi)
+const long double PI = M_PIl;							// pi
+const long double PI_2 = M_PI_2l;						// pi / 2
+const long double PI_4 = M_PI_4l;						// pi / 4
+const long double _1_PI = M_1_PIl;						// 1 / pi
+const long double _2_PI = M_2_PIl;						// 2 / pi
+const long double _2_SQRT_PI = M_2_SQRTPIl;				// 2 / sqrt(pi)
 
-float _Complex PI = (float)M_PI + 0.0_iF;				// pi
-float _Complex PI_2 = (float)M_PI_2 + 0.0_iF;			// pi / 2
-float _Complex PI_4 = (float)M_PI_4 + 0.0_iF;			// pi / 4
-float _Complex _1_PI = (float)M_1_PI + 0.0_iF;			// 1 / pi
-float _Complex _2_PI = (float)M_2_PI + 0.0_iF;			// 2 / pi
-float _Complex _2_SQRT_PI = (float)M_2_SQRTPI + 0.0_iF; // 2 / sqrt(pi)
+const float _Complex PI = (float)M_PI + 0.0_iF;			// pi
+const float _Complex PI_2 = (float)M_PI_2 + 0.0_iF;		// pi / 2
+const float _Complex PI_4 = (float)M_PI_4 + 0.0_iF;		// pi / 4
+const float _Complex _1_PI = (float)M_1_PI + 0.0_iF;	// 1 / pi
+const float _Complex _2_PI = (float)M_2_PI + 0.0_iF;	// 2 / pi
+const float _Complex _2_SQRT_PI = (float)M_2_SQRTPI + 0.0_iF; // 2 / sqrt(pi)
 
-double _Complex PI = M_PI + 0.0_iD;						// pi
-double _Complex PI_2 = M_PI_2 + 0.0_iD;					// pi / 2
-double _Complex PI_4 = M_PI_4 + 0.0_iD;					// pi / 4
-double _Complex _1_PI = M_1_PI + 0.0_iD;				// 1 / pi
-double _Complex _2_PI = M_2_PI + 0.0_iD;				// 2 / pi
-double _Complex _2_SQRT_PI = M_2_SQRTPI + 0.0_iD;		// 2 / sqrt(pi)
+const double _Complex PI = M_PI + 0.0_iD;				// pi
+const double _Complex PI_2 = M_PI_2 + 0.0_iD;			// pi / 2
+const double _Complex PI_4 = M_PI_4 + 0.0_iD;			// pi / 4
+const double _Complex _1_PI = M_1_PI + 0.0_iD;			// 1 / pi
+const double _Complex _2_PI = M_2_PI + 0.0_iD;			// 2 / pi
+const double _Complex _2_SQRT_PI = M_2_SQRTPI + 0.0_iD;	// 2 / sqrt(pi)
 
-long double _Complex PI = M_PIl + 0.0_iL;				// pi
-long double _Complex PI_2 = M_PI_2l + 0.0_iL;			// pi / 2
-long double _Complex PI_4 = M_PI_4l + 0.0_iL;			// pi / 4
-long double _Complex _1_PI = M_1_PIl + 0.0_iL;			// 1 / pi
-long double _Complex _2_PI = M_2_PIl + 0.0_iL;			// 2 / pi
-long double _Complex _2_SQRT_PI = M_2_SQRTPIl + 0.0_iL; // 2 / sqrt(pi)
+const long double _Complex PI = M_PIl + 0.0_iL;			// pi
+const long double _Complex PI_2 = M_PI_2l + 0.0_iL;		// pi / 2
+const long double _Complex PI_4 = M_PI_4l + 0.0_iL;		// pi / 4
+const long double _Complex _1_PI = M_1_PIl + 0.0_iL;	// 1 / pi
+const long double _Complex _2_PI = M_2_PIl + 0.0_iL;	// 2 / pi
+const long double _Complex _2_SQRT_PI = M_2_SQRTPIl + 0.0_iL; // 2 / sqrt(pi)
 
-float E = (float)M_E;									// e
-float LOG2_E = (float)M_LOG2E;							// log_2(e)
-float LOG10_E = (float)M_LOG10E;						// log_10(e)
-float LN_2 = (float)M_LN2;								// log_e(2)
-float LN_10 = (float)M_LN10;							// log_e(10)
-float SQRT_2 = (float)M_SQRT2;							// sqrt(2)
-float _1_SQRT_2 = (float)M_SQRT1_2;						// 1 / sqrt(2)
+const float E = (float)M_E;								// e
+const float LOG2_E = (float)M_LOG2E;					// log_2(e)
+const float LOG10_E = (float)M_LOG10E;					// log_10(e)
+const float LN_2 = (float)M_LN2;						// log_e(2)
+const float LN_10 = (float)M_LN10;						// log_e(10)
+const float SQRT_2 = (float)M_SQRT2;					// sqrt(2)
+const float _1_SQRT_2 = (float)M_SQRT1_2;				// 1 / sqrt(2)
 
-double E = M_E;											// e
-double LOG2_E = M_LOG2E;								// log_2(e)
-double LOG10_E = M_LOG10E;								// log_10(e)
-double LN_2 = M_LN2;									// log_e(2)
-double LN_10 = M_LN10;									// log_e(10)
-double SQRT_2 = M_SQRT2;								// sqrt(2)
-double _1_SQRT_2 = M_SQRT1_2;							// 1 / sqrt(2)
+const double E = M_E;									// e
+const double LOG2_E = M_LOG2E;							// log_2(e)
+const double LOG10_E = M_LOG10E;						// log_10(e)
+const double LN_2 = M_LN2;								// log_e(2)
+const double LN_10 = M_LN10;							// log_e(10)
+const double SQRT_2 = M_SQRT2;							// sqrt(2)
+const double _1_SQRT_2 = M_SQRT1_2;						// 1 / sqrt(2)
 
-long double E = M_El;									// e
-long double LOG2_E = M_LOG2El;							// log_2(e)
-long double LOG10_E = M_LOG10El;						// log_10(e)
-long double LN_2 = M_LN2l;								// log_e(2)
-long double LN_10 = M_LN10l;							// log_e(10)
-long double SQRT_2 = M_SQRT2l;							// sqrt(2)
-long double _1_SQRT_2 = M_SQRT1_2l;						// 1 / sqrt(2)
+const long double E = M_El;								// e
+const long double LOG2_E = M_LOG2El;					// log_2(e)
+const long double LOG10_E = M_LOG10El;					// log_10(e)
+const long double LN_2 = M_LN2l;						// log_e(2)
+const long double LN_10 = M_LN10l;						// log_e(10)
+const long double SQRT_2 = M_SQRT2l;					// sqrt(2)
+const long double _1_SQRT_2 = M_SQRT1_2l;				// 1 / sqrt(2)
 
-float _Complex E = M_E + 0.0_iF;						// e
-float _Complex LOG2_E = M_LOG2E + 0.0_iF;				// log_2(e)
-float _Complex LOG10_E = M_LOG10E + 0.0_iF;				// log_10(e)
-float _Complex LN_2 = M_LN2 + 0.0_iF;					// log_e(2)
-float _Complex LN_10 = M_LN10 + 0.0_iF;					// log_e(10)
-float _Complex SQRT_2 = M_SQRT2 + 0.0_iF;				// sqrt(2)
-float _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iF;			// 1 / sqrt(2)
+const float _Complex E = M_E + 0.0_iF;					// e
+const float _Complex LOG2_E = M_LOG2E + 0.0_iF;			// log_2(e)
+const float _Complex LOG10_E = M_LOG10E + 0.0_iF;		// log_10(e)
+const float _Complex LN_2 = M_LN2 + 0.0_iF;				// log_e(2)
+const float _Complex LN_10 = M_LN10 + 0.0_iF;			// log_e(10)
+const float _Complex SQRT_2 = M_SQRT2 + 0.0_iF;			// sqrt(2)
+const float _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iF;	// 1 / sqrt(2)
 
-double _Complex E = M_E + 0.0_iD;						// e
-double _Complex LOG2_E = M_LOG2E + 0.0_iD;				// log_2(e)
-double _Complex LOG10_E = M_LOG10E + 0.0_iD;			// log_10(e)
-double _Complex LN_2 = M_LN2 + 0.0_iD;					// log_e(2)
-double _Complex LN_10 = M_LN10 + 0.0_iD;				// log_e(10)
-double _Complex SQRT_2 = M_SQRT2 + 0.0_iD;				// sqrt(2)
-double _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iD;			// 1 / sqrt(2)
+const double _Complex E = M_E + 0.0_iD;					// e
+const double _Complex LOG2_E = M_LOG2E + 0.0_iD;		// log_2(e)
+const double _Complex LOG10_E = M_LOG10E + 0.0_iD;		// log_10(e)
+const double _Complex LN_2 = M_LN2 + 0.0_iD;			// log_e(2)
+const double _Complex LN_10 = M_LN10 + 0.0_iD;			// log_e(10)
+const double _Complex SQRT_2 = M_SQRT2 + 0.0_iD;		// sqrt(2)
+const double _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iD;	// 1 / sqrt(2)
 
-long double _Complex E = M_El + 0.0_iL;					// e
-long double _Complex LOG2_E = M_LOG2El + 0.0_iL;		// log_2(e)
-long double _Complex LOG10_E = M_LOG10El + 0.0_iL;		// log_10(e)
-long double _Complex LN_2 = M_LN2l + 0.0_iL;			// log_e(2)
-long double _Complex LN_10 = M_LN10l + 0.0_iL;			// log_e(10)
-long double _Complex SQRT_2 = M_SQRT2l + 0.0_iL;		// sqrt(2)
-long double _Complex _1_SQRT_2 = M_SQRT1_2l + 0.0_iL;	// 1 / sqrt(2)
+const long double _Complex E = M_El + 0.0_iL;			// e
+const long double _Complex LOG2_E = M_LOG2El + 0.0_iL;	// log_2(e)
+const long double _Complex LOG10_E = M_LOG10El + 0.0_iL; // log_10(e)
+const long double _Complex LN_2 = M_LN2l + 0.0_iL;		// log_e(2)
+const long double _Complex LN_10 = M_LN10l + 0.0_iL;	// log_e(10)
+const long double _Complex SQRT_2 = M_SQRT2l + 0.0_iL;	// sqrt(2)
+const long double _Complex _1_SQRT_2 = M_SQRT1_2l + 0.0_iL; // 1 / sqrt(2)
 
 // Local Variables: //
Index: libcfa/src/limits.hfa
===================================================================
--- libcfa/src/limits.hfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ libcfa/src/limits.hfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 18:06:52 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Sep 30 22:56:35 2020
-// Update Count     : 15
+// Last Modified On : Thu Mar  1 16:20:54 2018
+// Update Count     : 13
 //
 
@@ -18,131 +18,131 @@
 // Integral Constants
 
-extern signed char MIN;
-extern unsigned char MIN;
-extern short int MIN;
-extern unsigned short int MIN;
-extern int MIN;
-extern unsigned int MIN;
-extern long int MIN;
-extern unsigned long int MIN;
-extern long long int MIN;
-extern unsigned long long int MIN;
+extern const signed char MIN;
+extern const unsigned char MIN;
+extern const short int MIN;
+extern const unsigned short int MIN;
+extern const int MIN;
+extern const unsigned int MIN;
+extern const long int MIN;
+extern const unsigned long int MIN;
+extern const long long int MIN;
+extern const unsigned long long int MIN;
 
-extern signed char MAX;
-extern unsigned char MAX;
-extern short int MAX;
-extern unsigned short int MAX;
-extern int MAX;
-extern unsigned int MAX;
-extern long int MAX;
-extern unsigned long int MAX;
-extern long long int MAX;
-extern unsigned long long int MAX;
+extern const signed char MAX;
+extern const unsigned char MAX;
+extern const short int MAX;
+extern const unsigned short int MAX;
+extern const int MAX;
+extern const unsigned int MAX;
+extern const long int MAX;
+extern const unsigned long int MAX;
+extern const long long int MAX;
+extern const unsigned long long int MAX;
 
 // Floating-Point Constants
 
-extern float MIN;
-extern double MIN;
-extern long double MIN;
-extern float _Complex MIN;
-extern double _Complex MIN;
-extern long double _Complex MIN;
+extern const float MIN;
+extern const double MIN;
+extern const long double MIN;
+extern const float _Complex MIN;
+extern const double _Complex MIN;
+extern const long double _Complex MIN;
 
-extern float MAX;
-extern double MAX;
-extern long double MAX;
-extern float _Complex MAX;
-extern double _Complex MAX;
-extern long double _Complex MAX;
+extern const float MAX;
+extern const double MAX;
+extern const long double MAX;
+extern const float _Complex MAX;
+extern const double _Complex MAX;
+extern const long double _Complex MAX;
 
-extern float PI;										// pi
-extern float PI_2;										// pi / 2
-extern float PI_4;										// pi / 4
-extern float _1_PI;										// 1 / pi
-extern float _2_PI;										// 2 / pi
-extern float _2_SQRT_PI;								// 2 / sqrt(pi)
+extern const float PI;									// pi
+extern const float PI_2;								// pi / 2
+extern const float PI_4;								// pi / 4
+extern const float _1_PI;								// 1 / pi
+extern const float _2_PI;								// 2 / pi
+extern const float _2_SQRT_PI;							// 2 / sqrt(pi)
 
-extern double PI;										// pi
-extern double PI_2;										// pi / 2
-extern double PI_4;										// pi / 4
-extern double _1_PI;									// 1 / pi
-extern double _2_PI;									// 2 / pi
-extern double _2_SQRT_PI;								// 2 / sqrt(pi)
+extern const double PI;									// pi
+extern const double PI_2;								// pi / 2
+extern const double PI_4;								// pi / 4
+extern const double _1_PI;								// 1 / pi
+extern const double _2_PI;								// 2 / pi
+extern const double _2_SQRT_PI;							// 2 / sqrt(pi)
 
-extern long double PI;									// pi
-extern long double PI_2;								// pi / 2
-extern long double PI_4;								// pi / 4
-extern long double _1_PI;								// 1 / pi
-extern long double _2_PI;								// 2 / pi
-extern long double _2_SQRT_PI;							// 2 / sqrt(pi)
+extern const long double PI;							// pi
+extern const long double PI_2;							// pi / 2
+extern const long double PI_4;							// pi / 4
+extern const long double _1_PI;							// 1 / pi
+extern const long double _2_PI;							// 2 / pi
+extern const long double _2_SQRT_PI;					// 2 / sqrt(pi)
 
-extern float _Complex PI;								// pi
-extern float _Complex PI_2;								// pi / 2
-extern float _Complex PI_4;								// pi / 4
-extern float _Complex _1_PI;							// 1 / pi
-extern float _Complex _2_PI;							// 2 / pi
-extern float _Complex _2_SQRT_PI;						// 2 / sqrt(pi)
+extern const float _Complex PI;							// pi
+extern const float _Complex PI_2;						// pi / 2
+extern const float _Complex PI_4;						// pi / 4
+extern const float _Complex _1_PI;						// 1 / pi
+extern const float _Complex _2_PI;						// 2 / pi
+extern const float _Complex _2_SQRT_PI;					// 2 / sqrt(pi)
 
-extern double _Complex PI;								// pi
-extern double _Complex PI_2;							// pi / 2
-extern double _Complex PI_4;							// pi / 4
-extern double _Complex _1_PI;							// 1 / pi
-extern double _Complex _2_PI;							// 2 / pi
-extern double _Complex _2_SQRT_PI;						// 2 / sqrt(pi)
+extern const double _Complex PI;						// pi
+extern const double _Complex PI_2;						// pi / 2
+extern const double _Complex PI_4;						// pi / 4
+extern const double _Complex _1_PI;						// 1 / pi
+extern const double _Complex _2_PI;						// 2 / pi
+extern const double _Complex _2_SQRT_PI;				// 2 / sqrt(pi)
 
-extern long double _Complex PI;							// pi
-extern long double _Complex PI_2;						// pi / 2
-extern long double _Complex PI_4;						// pi / 4
-extern long double _Complex _1_PI;						// 1 / pi
-extern long double _Complex _2_PI;						// 2 / pi
-extern long double _Complex _2_SQRT_PI;					// 2 / sqrt(pi)
+extern const long double _Complex PI;					// pi
+extern const long double _Complex PI_2;					// pi / 2
+extern const long double _Complex PI_4;					// pi / 4
+extern const long double _Complex _1_PI;				// 1 / pi
+extern const long double _Complex _2_PI;				// 2 / pi
+extern const long double _Complex _2_SQRT_PI;			// 2 / sqrt(pi)
 
-extern float E;											// e
-extern float LOG2_E;									// log_2(e)
-extern float LOG10_E;									// log_10(e)
-extern float LN_2;										// log_e(2)
-extern float LN_10;										// log_e(10)
-extern float SQRT_2;									// sqrt(2)
-extern float _1_SQRT_2;									// 1 / sqrt(2)
+extern const float E;									// e
+extern const float LOG2_E;								// log_2(e)
+extern const float LOG10_E;								// log_10(e)
+extern const float LN_2;								// log_e(2)
+extern const float LN_10;								// log_e(10)
+extern const float SQRT_2;								// sqrt(2)
+extern const float _1_SQRT_2;							// 1 / sqrt(2)
 
-extern double E;										// e
-extern double LOG2_E;									// log_2(e)
-extern double LOG10_E;									// log_10(e)
-extern double LN_2;										// log_e(2)
-extern double LN_10;									// log_e(10)
-extern double SQRT_2;									// sqrt(2)
-extern double _1_SQRT_2;								// 1 / sqrt(2)
+extern const double E;									// e
+extern const double LOG2_E;								// log_2(e)
+extern const double LOG10_E;							// log_10(e)
+extern const double LN_2;								// log_e(2)
+extern const double LN_10;								// log_e(10)
+extern const double SQRT_2;								// sqrt(2)
+extern const double _1_SQRT_2;							// 1 / sqrt(2)
 
-extern long double E;									// e
-extern long double LOG2_E;								// log_2(e)
-extern long double LOG10_E;								// log_10(e)
-extern long double LN_2;								// log_e(2)
-extern long double LN_10;								// log_e(10)
-extern long double SQRT_2;								// sqrt(2)
-extern long double _1_SQRT_2;							// 1/sqrt(2)
+extern const long double E;								// e
+extern const long double LOG2_E;						// log_2(e)
+extern const long double LOG10_E;						// log_10(e)
+extern const long double LN_2;							// log_e(2)
+extern const long double LN_10;							// log_e(10)
+extern const long double SQRT_2;						// sqrt(2)
+extern const long double _1_SQRT_2;						// 1/sqrt(2)
 
-extern float _Complex E;								// e
-extern float _Complex LOG2_E;							// log_2(e)
-extern float _Complex LOG10_E;							// log_10(e)
-extern float _Complex LN_2;								// log_e(2)
-extern float _Complex LN_10;							// log_e(10)
-extern float _Complex SQRT_2;							// sqrt(2)
-extern float _Complex _1_SQRT_2;						// 1 / sqrt(2)
+extern const float _Complex E;							// e
+extern const float _Complex LOG2_E;						// log_2(e)
+extern const float _Complex LOG10_E;					// log_10(e)
+extern const float _Complex LN_2;						// log_e(2)
+extern const float _Complex LN_10;						// log_e(10)
+extern const float _Complex SQRT_2;						// sqrt(2)
+extern const float _Complex _1_SQRT_2;					// 1 / sqrt(2)
 
-extern double _Complex E;								// e
-extern double _Complex LOG2_E;							// log_2(e)
-extern double _Complex LOG10_E;							// log_10(e)
-extern double _Complex LN_2;							// log_e(2)
-extern double _Complex LN_10;							// log_e(10)
-extern double _Complex SQRT_2;							// sqrt(2)
-extern double _Complex _1_SQRT_2;						// 1 / sqrt(2)
+extern const double _Complex E;							// e
+extern const double _Complex LOG2_E;					// log_2(e)
+extern const double _Complex LOG10_E;					// log_10(e)
+extern const double _Complex LN_2;						// log_e(2)
+extern const double _Complex LN_10;						// log_e(10)
+extern const double _Complex SQRT_2;					// sqrt(2)
+extern const double _Complex _1_SQRT_2;					// 1 / sqrt(2)
 
-extern long double _Complex E;							// e
-extern long double _Complex LOG2_E;						// log_2(e)
-extern long double _Complex LOG10_E;					// log_10(e)
-extern long double _Complex LN_2;						// log_e(2)
-extern long double _Complex LN_10;						// log_e(10)
-extern long double _Complex SQRT_2;						// sqrt(2)
-extern long double _Complex _1_SQRT_2;					// 1 / sqrt(2)
+extern const long double _Complex E;					// e
+extern const long double _Complex LOG2_E;				// log_2(e)
+extern const long double _Complex LOG10_E;				// log_10(e)
+extern const long double _Complex LN_2;					// log_e(2)
+extern const long double _Complex LN_10;				// log_e(10)
+extern const long double _Complex SQRT_2;				// sqrt(2)
+extern const long double _Complex _1_SQRT_2;			// 1 / sqrt(2)
 
 // Local Variables: //
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ src/Concurrency/Keywords.cc	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -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.
  */
 
Index: tests/.expect/array.txt
===================================================================
--- tests/.expect/array.txt	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/.expect/array.txt	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -1,2 +1,2 @@
 array.cfa: In function '_X4mainFi___1':
-array.cfa:54:9: note: #pragma message: Compiled
+array.cfa:55:9: note: #pragma message: Compiled
Index: tests/.expect/const-init.txt
===================================================================
--- tests/.expect/const-init.txt	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
+++ tests/.expect/const-init.txt	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -0,0 +1,1 @@
+done
Index: tests/.expect/expression.txt
===================================================================
--- tests/.expect/expression.txt	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/.expect/expression.txt	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -1,2 +1,2 @@
 expression.cfa: In function '_X4mainFi___1':
-expression.cfa:88:9: note: #pragma message: Compiled
+expression.cfa:89:9: note: #pragma message: Compiled
Index: tests/.expect/limits.txt
===================================================================
--- tests/.expect/limits.txt	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/.expect/limits.txt	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -1,2 +1,2 @@
 limits.cfa: In function '_X4mainFi_iPPKc__1':
-limits.cfa:151:9: note: #pragma message: Compiled
+limits.cfa:154:9: note: #pragma message: Compiled
Index: tests/array.cfa
===================================================================
--- tests/array.cfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/array.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -1,11 +1,11 @@
-//                               -*- Mode: C -*- 
-// 
+//                               -*- Mode: C -*-
+//
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
 //
 // The contents of this file are covered under the licence agreement in the
 // file "LICENCE" distributed with Cforall.
-// 
+//
 // array.cfa -- test array declarations
-// 
+//
 // Author           : Peter A. Buhr
 // Created On       : Tue Feb 19 21:18:06 2019
@@ -13,5 +13,5 @@
 // Last Modified On : Sun Sep 27 09:05:40 2020
 // Update Count     : 4
-// 
+//
 
 int a1[0];
@@ -50,5 +50,7 @@
 
 int main() {
-	#pragma message( "Compiled" )						// force non-empty .expect file
+	#if !defined(NO_COMPILED_PRAGMA)
+		#pragma message( "Compiled" )	// force non-empty .expect file
+	#endif
 }
 
Index: tests/const-init.cfa
===================================================================
--- tests/const-init.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
+++ tests/const-init.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -0,0 +1,48 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// const-init.cfa -- tests of initializing constants
+//
+// Author           : Michael Brooks
+// Created On       : Tue Oct 06 22:00:00 2020
+// Last Modified By : Michael Brooks
+// Last Modified On : Tue Oct 06 22:00:00 2020
+// Update Count     : 1
+//
+
+/*
+
+This test shows non-crashing of generated code for constants with interesting initizers.
+The potential for these to crash is compiler dependent.
+
+There are two cases:
+1. static constants in one compilation unit (tested here)
+2. extern constants across compilation units (tested by libcfa being loadable, specifically
+   the constant declarations in libcfa/src/limits.cfa, which almost every test exercises,
+   including "hello;" but notably, the "limits" test does not exercise it because that test
+   is compile-only)
+
+Crashes that we have obsrved (#182 and build failures September 2020) are because the libcfa
+initialization is writing to a global variable (which the declaring program wants typed as 
+constant), while the compiler has placed this global in a read-only section.
+
+Compiler dependence includes:
+
+                          Case 1           Case 2
+GCC-6  on Ubuntu 16.04    Never crashed    Never crashed
+GCC-8  on both            Has crashed      Never crashed
+GCC-10 on Ubuntu 20.04    Has crashed      Has crashed
+
+For this test case to fail, with most other tests passing, would be a situation only ever
+observed with GCC-8.
+
+*/
+
+static const char foo = -1;
+
+int main() {
+    printf("done\n");
+}
Index: tests/exceptions/defaults.cfa
===================================================================
--- tests/exceptions/defaults.cfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/exceptions/defaults.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -55,5 +55,5 @@
 
 void unhandled_test(void) {
-	forall(dtype T | is_exception(T))
+	forall(dtype T, dtype V | is_exception(T, V))
 	void defaultTerminationHandler(T &) {
 		throw (unhandled_exception){};
Index: tests/expression.cfa
===================================================================
--- tests/expression.cfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/expression.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -84,4 +84,6 @@
 	(S)@{2}`mary;
 
-	#pragma message( "Compiled" )			// force non-empty .expect file
+	#if !defined(NO_COMPILED_PRAGMA)
+		#pragma message( "Compiled" )	// force non-empty .expect file
+	#endif
 } // main
Index: tests/limits.cfa
===================================================================
--- tests/limits.cfa	(revision 3ca7ef3948062c1961c924a6f0aa2299977428d8)
+++ tests/limits.cfa	(revision 40a1392abdce61c38a915c8e80359ca2813021f5)
@@ -13,4 +13,7 @@
 // Update Count     : 10
 //
+
+// Note: For testing the ability to load the constants defined in libcfa/src/limits.cfa,
+// see discussion in test const-init.
 
 #include <limits.hfa>
