Index: Jenkins/TestRegen
===================================================================
--- Jenkins/TestRegen	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ Jenkins/TestRegen	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -33,5 +33,5 @@
 			email()
 		}
-	} 
+	}
 	catch (Exception caughtError) {
 		email_error()
@@ -65,5 +65,5 @@
 
 	def install_dir = pwd tmp: true
-		
+
 	//Configure the conpilation (Output is not relevant)
 	//Use the current directory as the installation target so nothing
@@ -101,5 +101,5 @@
 		def email_subject = "[cforall dashboard][TEST REGEN# ${env.BUILD_NUMBER}] - Result"
 		def email_body = """This is an automated email from the Jenkins build machine. It was
-generated http://plg2:8082/dashboard.
+generated https://cforall.uwaterloo.ca:8082/dashboard.html.
 
 Please apply the required changes using the following method :
@@ -118,5 +118,5 @@
 	def email_subject = "[cforall dashboard][TEST REGEN# ${env.BUILD_NUMBER}] - FAILURE"
 	def email_body = """This is an automated email from the Jenkins build machine. It was
-generated http://plg2:8082/dashboard.
+generated https://cforall.uwaterloo.ca:8082/dashboard.html.
 
 Test generation encoutered an error please see attached logs
Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ Jenkinsfile	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -174,5 +174,5 @@
 
 def notify_server(int wait) {
-	sh """curl --data "wait=${wait}" -X POST http://plg2:8082/jenkins/notify > /dev/null || true"""
+	sh """curl --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
 	return
 }
@@ -329,5 +329,5 @@
 
 		//Then publish the results
-		sh 'curl -H \'Content-Type: application/json\' --data @bench.json http://plg2:8082/jenkins/publish > /dev/null || true'
+		sh 'curl -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
 	}
 }
Index: README
===================================================================
--- README	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ README	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -107,5 +107,5 @@
 - the implicit coercion of structure types to the type of their first member is
   not implemented
-	
+
 Who is responsible for cfa-cc?
 ------------------------------
@@ -115,3 +115,3 @@
 The Cforall project maintains a web page:
 
-	http://plg.uwaterloo.ca/~cforall
+	https://cforall.uwaterloo.ca
Index: doc/bibliography/pl.bib
===================================================================
--- doc/bibliography/pl.bib	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ doc/bibliography/pl.bib	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -377,4 +377,17 @@
 }
 
+@article{Hoare61,
+    keywords	= {quick sort},
+    contributer	= {pabuhr@plg},
+    author	= {C. A. R. Hoare},
+    title	= {Algorithms 63/64: Partition/Quicksort},
+    journal	= cacm,
+    volume	= 4,
+    number	= 7,
+    month	= jul,
+    year	= 1961,
+    pages	= {321},
+}
+
 @article{Cormack81,
     keywords	= {},
@@ -635,4 +648,15 @@
     year	= 2008,
     pages	= {8-15},
+}
+
+@article{Joung00,
+    author	= {Joung, Yuh-Jzer},
+    title	= {Asynchronous group mutual exclusion},
+    journal	= {Distributed Computing},
+    year	= {2000},
+    month	= {Nov},
+    volume	= {13},
+    number	= {4},
+    pages	= {189--206},
 }
 
@@ -5791,5 +5815,5 @@
 @manual{Python,
     keywords	= {Python},
-    contributer	= {pabuhr},
+    contributer	= {pabuhr@plg},
     title	= {Python Reference Manual, Release 2.5},
     author	= {Guido van Rossum},
@@ -5822,15 +5846,17 @@
 }
 
-@article{Hoare61,
-    keywords	= {quick sort},
-    contributer	= {pabuhr@plg},
-    author	= {C. A. R. Hoare},
-    title	= {Algorithms 63/64: Partition/Quicksort},
-    journal	= cacm,
-    volume	= 4,
-    number	= 7,
-    month	= jul,
-    year	= 1961,
-    pages	= {321},
+@article{Nakaike15,
+    keywords	= {hardware transactional memory},
+    contributer	= {pabuhr@plg},
+    author	= {Nakaike, Takuya and Odaira, Rei and Gaudet, Matthew and Michael, Maged M. and Tomari, Hisanobu},
+    title	= {Quantitative Comparison of Hardware Transactional Memory for Blue Gene/Q, zEnterprise {EC12}, {I}ntel Core, and {POWER8}},
+    journal	= {SIGARCH Comput. Archit. News},
+    volume	= {43},
+    number	= {3},
+    month	= jun,
+    year	= {2015},
+    pages	= {144--157},
+    publisher	= {ACM},
+    address	= {New York, NY, USA},
 }
 
Index: doc/papers/concurrency/Paper.tex
===================================================================
--- doc/papers/concurrency/Paper.tex	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ doc/papers/concurrency/Paper.tex	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -70,6 +70,4 @@
 %\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}
 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
-%\def\myCHarFont{\fontencoding{T1}\selectfont}%
-% \def\{{\ttfamily\upshape\myCHarFont \char`\}}}%
 
 \renewcommand*{\thefootnote}{\Alph{footnote}} % hack because fnsymbol does not work
@@ -741,12 +739,12 @@
 The coroutine main's stack holds the state for the next generation, @f1@ and @f2@, and the code has the three suspend points, representing the three states in the Fibonacci formula, to context switch back to the caller's resume.
 The interface function, @next@, takes a Fibonacci instance and context switches to it using @resume@;
-on return, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
+on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
 The first @resume@ is special because it cocalls the coroutine at its coroutine main and allocates the stack;
 when the coroutine main returns, its stack is deallocated.
 Hence, @Fib@ is an object at creation, transitions to a coroutine on its first resume, and transitions back to an object when the coroutine main finishes.
 Figure~\ref{f:Coroutine1State} shows the coroutine version of the C version in Figure~\ref{f:ExternalState}.
-Coroutine generators are called \newterm{output coroutines} because values are returned by the coroutine.
-
-Figure~\ref{f:CFAFmt} shows an \newterm{input coroutine}, @Format@, for restructuring text into groups of character blocks of fixed size.
+Coroutine generators are called \newterm{output coroutines} because values are only returned.
+
+Figure~\ref{f:CFAFmt} shows an \newterm{input coroutine}, @Format@, for restructuring text into groups of characters of fixed-size blocks.
 For example, the input of the left is reformatted into the output on the right.
 \begin{quote}
@@ -763,5 +761,5 @@
 \end{tabular}
 \end{quote}
-The example takes advantage of resuming coroutines in the constructor to prime the coroutine loops so the first character sent for formatting appears inside the nested loops.
+The example takes advantage of resuming a coroutine in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops.
 The destruction provides a newline if formatted text ends with a full line.
 Figure~\ref{f:CFmt} shows the C equivalent formatter, where the loops of the coroutine are flatten (linearized) and rechecked on each call because execution location is not retained between calls.
@@ -778,5 +776,5 @@
 void main( Format & fmt ) with( fmt ) {
 	for ( ;; ) {	
-		for ( g = 0; g < 5; g += 1 ) {  // group
+		for ( g = 0; g < 5; g += 1 ) {      // group
 			for ( b = 0; b < 4; b += 1 ) { // block
 				`suspend();`
@@ -814,5 +812,5 @@
 };
 void format( struct Format * fmt ) {
-	if ( fmt->ch != -1 ) { // not EOF
+	if ( fmt->ch != -1 ) {      // not EOF ?
 		printf( "%c", fmt->ch );
 		fmt->b += 1;
@@ -823,5 +821,5 @@
 		}
 		if ( fmt->g == 5 ) {  // group
-			printf( "\n" );      // separator
+			printf( "\n" );     // separator
 			fmt->g = 0;
 		}
@@ -850,6 +848,6 @@
 
 The previous examples are \newterm{asymmetric (semi) coroutine}s because one coroutine always calls a resuming function for another coroutine, and the resumed coroutine always suspends back to its last resumer, similar to call/return for normal functions.
-However, there is no stack growth because @resume@/@suspend@ context switch to an existing stack frames rather than create a new one.
-\newterm{Symmetric (full) coroutine}s have a coroutine call a resuming function for another coroutine, which eventually forms a cycle.
+However, there is no stack growth because @resume@/@suspend@ context switch to existing stack-frames rather than create new ones.
+\newterm{Symmetric (full) coroutine}s have a coroutine call a resuming function for another coroutine, which eventually forms a resuming-call cycle.
 (The trivial cycle is a coroutine resuming itself.)
 This control flow is similar to recursion for normal routines, but again there is no stack growth from the context switch.
@@ -935,17 +933,17 @@
 The @start@ function communicates both the number of elements to be produced and the consumer into the producer's coroutine structure.
 Then the @resume@ to @prod@ creates @prod@'s stack with a frame for @prod@'s coroutine main at the top, and context switches to it.
-@prod@'s coroutine main starts, creates local variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random vales, calling the consumer to deliver the values, and printing the status returned from the consumer.
+@prod@'s coroutine main starts, creates local variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random values, calling the consumer to deliver the values, and printing the status returned from the consumer.
 
 The producer call to @delivery@ transfers values into the consumer's communication variables, resumes the consumer, and returns the consumer status.
 For the first resume, @cons@'s stack is initialized, creating local variables retained between subsequent activations of the coroutine.
-The consumer iterates until the @done@ flag is set, prints, increments status, and calls back to the producer's @payment@ member, and on return prints the receipt from the producer and increments the money for the next payment.
-The call from the consumer to the producer's @payment@ member introduces the cycle between producer and consumer.
+The consumer iterates until the @done@ flag is set, prints, increments status, and calls back to the producer via @payment@, and on return from @payment@, prints the receipt from the producer and increments @money@ (inflation).
+The call from the consumer to the @payment@ introduces the cycle between producer and consumer.
 When @payment@ is called, the consumer copies values into the producer's communication variable and a resume is executed.
-The context switch restarts the producer at the point where it was last context switched and it continues in member @delivery@ after the resume.
-
-The @delivery@ member returns the status value in @prod@'s @main@ member, where the status is printed.
+The context switch restarts the producer at the point where it was last context switched, so it continues in @delivery@ after the resume.
+
+@delivery@ returns the status value in @prod@'s coroutine main, where the status is printed.
 The loop then repeats calling @delivery@, where each call resumes the consumer coroutine.
 The context switch to the consumer continues in @payment@.
-The consumer increments and returns the receipt to the call in @cons@'s @main@ member.
+The consumer increments and returns the receipt to the call in @cons@'s coroutine main.
 The loop then repeats calling @payment@, where each call resumes the producer coroutine.
 
@@ -954,105 +952,34 @@
 The context switch restarts @cons@ in @payment@ and it returns with the last receipt.
 The consumer terminates its loops because @done@ is true, its @main@ terminates, so @cons@ transitions from a coroutine back to an object, and @prod@ reactivates after the resume in @stop@.
-The @stop@ member returns and @prod@'s @main@ member terminates.
+@stop@ returns and @prod@'s coroutine main terminates.
 The program main restarts after the resume in @start@.
-The @start@ member returns and the program main terminates.
-
-
-\subsubsection{Construction}
-
-One important design challenge for implementing coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs to connect the fully constructed object into the system.
-In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling.
-However, the underlying challenge remains the same for coroutines and threads.
-
-The runtime system needs to create the coroutine's stack and, more importantly, prepare it for the first resumption.
-The timing of the creation is non-trivial since users expect both to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor.
-There are several solutions to this problem but the chosen option effectively forces the design of the coroutine.
-
-Furthermore, \CFA faces an extra challenge as polymorphic routines create invisible thunks when cast to non-polymorphic routines and these thunks have function scope.
-For example, the following code, while looking benign, can run into undefined behaviour because of thunks:
-
-\begin{cfa}
-// async: Runs function asynchronously on another thread
-forall(otype T)
-extern void async(void (*func)(T*), T* obj);
-
-forall(otype T)
-void noop(T*) {}
-
-void bar() {
-	int a;
-	async(noop, &a); // start thread running noop with argument a
-}
-\end{cfa}
-
-The generated C code\footnote{Code trimmed down for brevity} creates a local thunk to hold type information:
-
-\begin{cfa}
-extern void async(/* omitted */, void (*func)(void*), void* obj);
-
-void noop(/* omitted */, void* obj){}
-
-void bar(){
-	int a;
-	void _thunk0(int* _p0){
-		/* omitted */
-		noop(/* omitted */, _p0);
-	}
-	/* omitted */
-	async(/* omitted */, ((void (*)(void*))(&_thunk0)), (&a));
-}
-\end{cfa}
-The problem in this example is a storage management issue, the function pointer @_thunk0@ is only valid until the end of the block, which limits the viable solutions because storing the function pointer for too long causes undefined behaviour; \ie the stack-based thunk being destroyed before it can be used.
-This challenge is an extension of challenges that come with second-class routines.
-Indeed, GCC nested routines also have the limitation that nested routine cannot be passed outside of the declaration scope.
-The case of coroutines and threads is simply an extension of this problem to multiple call stacks.
-
-
-\subsubsection{Alternative: Composition}
-
-One solution to this challenge is to use composition/containment, where coroutine fields are added to manage the coroutine.
-
-\begin{cfa}
-struct Fibonacci {
-	int fn; // used for communication
-	coroutine c; // composition
-};
-
-void FibMain(void*) {
-	//...
-}
-
-void ?{}(Fibonacci& this) {
-	this.fn = 0;
-	// Call constructor to initialize coroutine
-	(this.c){myMain};
-}
-\end{cfa}
-The downside of this approach is that users need to correctly construct the coroutine handle before using it.
-Like any other objects, the user must carefully choose construction order to prevent usage of objects not yet constructed.
-However, in the case of coroutines, users must also pass to the coroutine information about the coroutine main, like in the previous example.
-This opens the door for user errors and requires extra runtime storage to pass at runtime information that can be known statically.
-
-
-\subsubsection{Alternative: Reserved keyword}
-
-The next alternative is to use language support to annotate coroutines as follows:
-\begin{cfa}
-coroutine Fibonacci {
-	int fn; // used for communication
-};
-\end{cfa}
-The @coroutine@ keyword means the compiler can find and inject code where needed.
-The downside of this approach is that it makes coroutine a special case in the language.
-Users wanting to extend coroutines or build their own for various reasons can only do so in ways offered by the language.
-Furthermore, implementing coroutines without language supports also displays the power of the programming language used.
-While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed by users without using the language support.
-The reserved keywords are only present to improve ease of use for the common cases.
-
-
-\subsubsection{Alternative: Lambda Objects}
+@start@ returns and the program main terminates.
+
+
+\subsection{Coroutine Implementation}
+
+A significant implementation challenge for coroutines (and threads, see section \ref{threads}) is adding extra fields and executing code after/before the coroutine constructor/destructor and coroutine main to create/initialize/de-initialize/destroy extra fields and the stack.
+There are several solutions to this problem and the chosen option forced the \CFA coroutine design.
+
+Object-oriented inheritance provides extra fields and code in a restricted context, but it requires programmers to explicitly perform the inheritance:
+\begin{cfa}
+struct mycoroutine $\textbf{\textsf{inherits}}$ baseCoroutine { ... }
+\end{cfa}
+and the programming language (and possibly its tool set, \eg debugger) may need to understand @baseCoroutine@ because of the stack.
+Furthermore, the execution of constructs/destructors is in the wrong order for certain operations, \eg for threads;
+\eg, if the thread is implicitly started, it must start \emph{after} all constructors, because the thread relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
+
+An alternatively is composition:
+\begin{cfa}
+struct mycoroutine {
+	... // declarations
+	baseCoroutine dummy; // composition, last declaration
+}
+\end{cfa}
+which also requires an explicit declaration that must be the last one to ensure correct initialization order.
+However, there is nothing preventing wrong placement or multiple declarations.
 
 For coroutines as for threads, many implementations are based on routine pointers or function objects~\cite{Butenhof97, C++14, MS:VisualC++, BoostCoroutines15}.
-For example, Boost implements coroutines in terms of four functor object types:
+For example, Boost implements coroutines in terms of four functor object-types:
 \begin{cfa}
 asymmetric_coroutine<>::pull_type
@@ -1061,94 +988,115 @@
 symmetric_coroutine<>::yield_type
 \end{cfa}
-Often, the canonical threading paradigm in languages is based on function pointers, @pthread@ being one of the most well-known examples.
-The main problem of this approach is that the thread usage is limited to a generic handle that must otherwise be wrapped in a custom type.
-Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda based coroutines adds very little.
-
-A variation of this would be to use a simple function pointer in the same way @pthread@ does for threads:
-\begin{cfa}
-void foo( coroutine_t cid, void* arg ) {
-	int* value = (int*)arg;
+Similarly, the canonical threading paradigm is often based on function pointers, \eg @pthread@~\cite{pthreads}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}.
+However, the generic thread-handle (identifier) is limited (few operations), unless it is wrapped in a custom type.
+\begin{cfa}
+void mycor( coroutine_t cid, void * arg ) {
+	int * value = (int *)arg;				$\C{// type unsafe, pointer-size only}$
 	// Coroutine body
 }
-
 int main() {
-	int value = 0;
-	coroutine_t cid = coroutine_create( &foo, (void*)&value );
-	coroutine_resume( &cid );
-}
-\end{cfa}
-This semantics is more common for thread interfaces but coroutines work equally well.
-As discussed in section \ref{threads}, this approach is superseded by static approaches in terms of expressivity.
-
-
-\subsubsection{Alternative: Trait-Based Coroutines}
-
-Finally, the underlying approach, which is the one closest to \CFA idioms, is to use trait-based lazy coroutines.
-This approach defines a coroutine as anything that satisfies the trait @is_coroutine@ (as defined below) and is used as a coroutine.
-
-\begin{cfa}
-trait is_coroutine(dtype T) {
-      void main(T& this);
-      coroutine_desc* get_coroutine(T& this);
+	int input = 0, output;
+	coroutine_t cid = coroutine_create( &mycor, (void *)&input ); $\C{// type unsafe, pointer-size only}$
+	coroutine_resume( cid, (void *)input, (void **)&output ); $\C{// type unsafe, pointer-size only}$
+}
+\end{cfa}
+Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda-based coroutines adds very little.
+
+The selected approach is to use language support by introducing a new kind of aggregate (structure):
+\begin{cfa}
+coroutine Fibonacci {
+	int fn; // communication variables
 };
-
-forall( dtype T | is_coroutine(T) ) void suspend(T&);
-forall( dtype T | is_coroutine(T) ) void resume (T&);
-\end{cfa}
-This ensures that an object is not a coroutine until @resume@ is called on the object.
-Correspondingly, any object that is passed to @resume@ is a coroutine since it must satisfy the @is_coroutine@ trait to compile.
+\end{cfa}
+The @coroutine@ keyword means the compiler (and tool set) can find and inject code where needed.
+The downside of this approach is that it makes coroutine a special case in the language.
+Users wanting to extend coroutines or build their own for various reasons can only do so in ways offered by the language.
+Furthermore, implementing coroutines without language supports also displays the power of a programming language.
+While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed without using the language support.
+The reserved keyword eases use for the common cases.
+
+Part of the mechanism to generalize coroutines is using a \CFA trait, which defines a coroutine as anything satisfying the trait @is_coroutine@, and this trait is used to restrict coroutine-manipulation functions:
+\begin{cfa}
+trait is_coroutine( dtype T ) {
+      void main( T & this );
+      coroutine_desc * get_coroutine( T & this );
+};
+forall( dtype T | is_coroutine(T) ) void get_coroutine( T & );
+forall( dtype T | is_coroutine(T) ) void suspend( T & );
+forall( dtype T | is_coroutine(T) ) void resume( T & );
+\end{cfa}
+This definition ensures there is a statically-typed @main@ function that is the starting point (first stack frame) of a coroutine.
+No return value or additional parameters are necessary for this function, because the coroutine type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values.
+As well, any object passed to @suspend@ and @resume@ is a coroutine since it must satisfy the @is_coroutine@ trait to compile.
 The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ routine.
-The \CFA keyword @coroutine@ simply has the effect of implementing the getter and forward declarations required for users to implement the main routine.
-
-\begin{center}
-\begin{tabular}{c c c}
-\begin{cfa}[tabsize=3]
-coroutine MyCoroutine {
-	int someValue;
+The \CFA keyword @coroutine@ implicitly implements the getter and forward declarations required for implementing the coroutine main:
+\begin{cquote}
+\begin{tabular}{@{}ccc@{}}
+\begin{cfa}
+coroutine MyCor {
+	int value;
+
 };
-\end{cfa} & == & \begin{cfa}[tabsize=3]
-struct MyCoroutine {
-	int someValue;
-	coroutine_desc __cor;
+\end{cfa}
+& {\Large $\Rightarrow$} &
+\begin{tabular}{@{}ccc@{}}
+\begin{cfa}
+struct MyCor {
+	int value;
+	coroutine_desc cor;
 };
-
-static inline
-coroutine_desc* get_coroutine(
-	struct MyCoroutine& this
-) {
-	return &this.__cor;
-}
-
-void main(struct MyCoroutine* this);
+\end{cfa}
+&
+\begin{cfa}
+static inline coroutine_desc *
+get_coroutine( MyCor & this ) {
+	return &this.cor;
+}
+\end{cfa}
+&
+\begin{cfa}
+void main( MyCor * this );
+
+
+
 \end{cfa}
 \end{tabular}
-\end{center}
-
-The combination of these two approaches allows users new to coroutining and concurrency to have an easy and concise specification, while more advanced users have tighter control on memory layout and initialization.
-
-\subsection{Thread Interface}\label{threads}
-The basic building blocks of multithreading in \CFA are \textbf{cfathread}.
-Both user and kernel threads are supported, where user threads are the concurrency mechanism and kernel threads are the parallel mechanism.
-User threads offer a flexible and lightweight interface.
-A thread can be declared using a struct declaration @thread@ as follows:
-
-\begin{cfa}
-thread foo {};
-\end{cfa}
-
-As for coroutines, the keyword is a thin wrapper around a \CFA trait:
-
-\begin{cfa}
-trait is_thread(dtype T) {
-      void ^?{}(T & mutex this);
-      void main(T & this);
-      thread_desc* get_thread(T & this);
+\end{tabular}
+\end{cquote}
+The combination of these two approaches allows an easy and concise specification to coroutining (and concurrency) for normal users, while more advanced users have tighter control on memory layout and initialization.
+
+
+\subsection{Thread Interface}
+\label{threads}
+
+Both user and kernel threads are supported, where user threads provide concurrency and kernel threads provide parallelism.
+Like coroutines and for the same design reasons, the selected approach for user threads is to use language support by introducing a new kind of aggregate (structure) and a \CFA trait:
+\begin{cquote}
+\begin{tabular}{@{}c@{\hspace{2\parindentlnth}}c@{}}
+\begin{cfa}
+thread myThread {
+	// communication variables
 };
-\end{cfa}
-
-Obviously, for this thread implementation to be useful it must run some user code.
-Several other threading interfaces use a function-pointer representation as the interface of threads (for example \Csharp~\cite{Csharp} and Scala~\cite{Scala}).
-However, this proposal considers that statically tying a @main@ routine to a thread supersedes this approach.
-Since the @main@ routine is already a special routine in \CFA (where the program begins), it is a natural extension of the semantics to use overloading to declare mains for different threads (the normal main being the main of the initial thread).
+
+
+\end{cfa}
+&
+\begin{cfa}
+trait is_thread( dtype T ) {
+      void main( T & this );
+      thread_desc * get_thread( T & this );
+      void ^?{}( T & `mutex` this );
+};
+\end{cfa}
+\end{tabular}
+\end{cquote}
+(The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitors}.)
+Like a coroutine, the statically-typed @main@ function is the starting point (first stack frame) of a user thread.
+The difference is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates an instance of @main@;
+whereas, a user thread receives its own thread from the runtime system, which starts in @main@ as some point after the thread constructor is run.\footnote{
+The \lstinline@main@ function is already a special routine in C (where the program begins), so it is a natural extension of the semantics to use overloading to declare mains for different coroutines/threads (the normal main being the main of the initial thread).}
+No return value or additional parameters are necessary for this function, because the task type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values.
+
+\begin{comment} % put in appendix with coroutine version ???
 As such the @main@ routine of a thread can be defined as
 \begin{cfa}
@@ -1189,149 +1137,133 @@
 }
 \end{cfa}
-
 A consequence of the strongly typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \textbf{api}.
-
-Of course, for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution.
-While using an \textbf{api} such as @fork@ and @join@ is relatively common in the literature, such an interface is unnecessary.
-Indeed, the simplest approach is to use \textbf{raii} principles and have threads @fork@ after the constructor has completed and @join@ before the destructor runs.
-\begin{cfa}
-thread World;
-
-void main(World & this) {
+\end{comment}
+
+For user threads to be useful, it must be possible to start and stop the underlying thread, and wait for it to complete execution.
+While using an API such as @fork@ and @join@ is relatively common, such an interface is awkward and unnecessary.
+A simple approach is to use allocation/deallocation principles, and have threads implicitly @fork@ after construction and @join@ before destruction.
+\begin{cfa}
+thread World {};
+void main( World & this ) {
 	sout | "World!" | endl;
 }
-
-void main() {
-	World w;
-	// Thread forks here
-
-	// Printing "Hello " and "World!" are run concurrently
-	sout | "Hello " | endl;
-
-	// Implicit join at end of scope
-}
-\end{cfa}
-
-This semantic has several advantages over explicit semantics: a thread is always started and stopped exactly once, users cannot make any programming errors, and it naturally scales to multiple threads meaning basic synchronization is very simple.
-
-\begin{cfa}
-thread MyThread {
-	//...
+int main() {
+	World w`[10]`;							$\C{// implicit forks after creation}$
+	sout | "Hello " | endl;					$\C{// "Hello " and 10 "World!" printed concurrently}$
+}											$\C{// implicit joins before destruction}$
+\end{cfa}
+This semantics ensures a thread is started and stopped exactly once, eliminating some programming error, and scales to multiple threads for basic (termination) synchronization.
+This tree-structure (lattice) create/delete from C block-structure is generalized by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created.
+\begin{cfa}
+int main() {
+	MyThread * heapLived;
+	{
+		MyThread blockLived;				$\C{// fork block-based thread}$
+		heapLived = `new`( MyThread );		$\C{// fork heap-based thread}$
+		...
+	}										$\C{// join block-based thread}$
+	...
+	`delete`( heapLived );					$\C{// join heap-based thread}$
+}
+\end{cfa}
+The heap-based approach allows arbitrary thread-creation topologies, with respect to fork/join-style concurrency.
+
+Figure~\ref{s:ConcurrentMatrixSummation} shows concurrently adding the rows of a matrix and then totalling the subtotals sequential, after all the row threads have terminated.
+The program uses heap-based threads because each thread needs different constructor values.
+(Python provides a simple iteration mechanism to initialize array elements to different values allowing stack allocation.)
+The allocation/deallocation pattern appears unusual because allocated objects are immediately deleted without any intervening code.
+However, for threads, the deletion provides implicit synchronization, which is the intervening code.
+While the subtotals are added in linear order rather than completion order, which slight inhibits concurrency, the computation is restricted by the critical-path thread (\ie the thread that takes the longest), and so any inhibited concurrency is very small as totalling the subtotals is trivial.
+
+\begin{figure}
+\begin{cfa}
+thread Adder {
+    int * row, cols, & subtotal;			$\C{// communication}$
 };
-
-// main
-void main(MyThread& this) {
-	//...
-}
-
-void foo() {
-	MyThread thrds[10];
-	// Start 10 threads at the beginning of the scope
-
-	DoStuff();
-
-	// Wait for the 10 threads to finish
-}
-\end{cfa}
-
-However, one of the drawbacks of this approach is that threads always form a tree where nodes must always outlive their children, \ie they are always destroyed in the opposite order of construction because of C scoping rules.
-This restriction is relaxed by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created.
-
-\begin{cfa}
-thread MyThread {
-	//...
-};
-
-void main(MyThread& this) {
-	//...
-}
-
-void foo() {
-	MyThread* long_lived;
-	{
-		// Start a thread at the beginning of the scope
-		MyThread short_lived;
-
-		// create another thread that will outlive the thread in this scope
-		long_lived = new MyThread;
-
-		DoStuff();
-
-		// Wait for the thread short_lived to finish
-	}
-	DoMoreStuff();
-
-	// Now wait for the long_lived to finish
-	delete long_lived;
-}
-\end{cfa}
-
-
-% ======================================================================
-% ======================================================================
-\section{Concurrency}
-% ======================================================================
-% ======================================================================
-Several tools can be used to solve concurrency challenges.
-Since many of these challenges appear with the use of mutable shared state, some languages and libraries simply disallow mutable shared state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}).
-In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (channels~\cite{CSP,Go} for example).
-However, in languages that use routine calls as their core abstraction mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (\ie message passing versus routine calls).
-This distinction in turn means that, in order to be effective, programmers need to learn two sets of design patterns.
+void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
+    adder.[ row, cols, &subtotal ] = [ row, cols, &subtotal ];
+}
+void main( Adder & adder ) with( adder ) {
+    subtotal = 0;
+    for ( int c = 0; c < cols; c += 1 ) {
+		subtotal += row[c];
+    }
+}
+int main() {
+    const int rows = 10, cols = 1000;
+    int matrix[rows][cols], subtotals[rows], total = 0;
+    // read matrix
+    Adder * adders[rows];
+    for ( int r = 0; r < rows; r += 1 ) {	$\C{// start threads to sum rows}$
+		adders[r] = new( matrix[r], cols, &subtotals[r] );
+    }
+    for ( int r = 0; r < rows; r += 1 ) {	$\C{// wait for threads to finish}$
+		delete( adders[r] );				$\C{// termination join}$
+		total += subtotals[r];				$\C{// total subtotal}$
+    }
+    sout | total | endl;
+}
+\end{cfa}
+\caption{Concurrent Matrix Summation}
+\label{s:ConcurrentMatrixSummation}
+\end{figure}
+
+
+\section{Synchronization / Mutual Exclusion}
+
+Uncontrolled non-deterministic execution is meaningless.
+To reestablish meaningful execution requires mechanisms to reintroduce determinism (control non-determinism), called synchronization and mutual exclusion, where synchronization is a timing relationship among threads and mutual exclusion is an access-control mechanism on data shared by threads.
+Since many deterministic challenges appear with the use of mutable shared state, some languages/libraries disallow it (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka~\cite{Akka} (Scala)).
+In these paradigms, interaction among concurrent objects is performed by stateless message-passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (\eg channels~\cite{CSP,Go}).
+However, in call/return-based languages, these approaches force a clear distinction (\ie introduce a new programming paradigm) between non-concurrent and concurrent computation (\ie function call versus message passing).
+This distinction means a programmers needs to learn two sets of design patterns.
 While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account.
-
-Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and shared objects.
-At the lowest level, concurrent paradigms are implemented as atomic operations and locks.
-Many such mechanisms have been proposed, including semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}.
-However, for productivity reasons it is desirable to have a higher-level construct be the core concurrency paradigm~\cite{Hochstein05}.
-
-An approach that is worth mentioning because it is gaining in popularity is transactional memory~\cite{Herlihy93}.
-While this approach is even pursued by system languages like \CC~\cite{Cpp-Transactions}, the performance and feature set is currently too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.
-
-One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared-memory systems, is the \emph{monitor}.
+In contrast, approaches based on statefull models more closely resemble the standard call/return programming-model, resulting in a single programming paradigm.
+
+At the lowest level, concurrent control is implemented as atomic operations, upon which different kinds of locks mechanism are constructed, \eg semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}.
+However, for productivity it is always desirable to use the highest-level construct that provides the necessary efficiency~\cite{Hochstein05}.
+A newer approach is transactional memory~\cite{Herlihy93}.
+While this approach is pursued in hardware~\cite{Nakaike15} and system languages, like \CC~\cite{Cpp-Transactions}, the performance and feature set is still too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.
+
+One of the most natural, elegant, and efficient mechanisms for synchronization and mutual exclusion for shared-memory systems is the \emph{monitor}.
 Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}.
-Many programming languages---\eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs.
+Many programming languages -- \eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java} -- provide monitors as explicit language constructs.
 In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors.
-For these reasons, this project proposes monitors as the core concurrency construct.
-
-
-\subsection{Basics}
-
-Non-determinism requires concurrent systems to offer support for mutual-exclusion and synchronization.
-Mutual-exclusion is the concept that only a fixed number of threads can access a critical section at any given time, where a critical section is a group of instructions on an associated portion of data that requires the restricted access.
-On the other hand, synchronization enforces relative ordering of execution and synchronization tools provide numerous mechanisms to establish timing relationships among threads.
-
-
-\subsubsection{Mutual-Exclusion}
-
-As mentioned above, mutual-exclusion is the guarantee that only a fix number of threads can enter a critical section at once.
+For these reasons, this project proposes monitors as the core concurrency construct, upon which even higher-level approaches can be easily constructed..
+
+
+\subsection{Mutual Exclusion}
+
+A group of instructions manipulating a specific instance of shared data that must be performed atomically is called an (individual) \newterm{critical-section}~\cite{Dijkstra65}.
+A generalization is a \newterm{group critical-section}~\cite{Joung00}, where multiple tasks with the same session may use the resource simultaneously, but different sessions may not use the resource simultaneously.
+The readers/writer problem~\cite{Courtois71} is an instance of a group critical-section, where readers have the same session and all writers have a unique session.
+\newterm{Mutual exclusion} enforces the correction number of threads are using a critical section at the same time.
+
 However, many solutions exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use.
-Methods range from low-level locks, which are fast and flexible but require significant attention to be correct, to  higher-level concurrency techniques, which sacrifice some performance in order to improve ease of use.
-Ease of use comes by either guaranteeing some problems cannot occur (\eg being deadlock free) or by offering a more explicit coupling between data and corresponding critical section.
+Methods range from low-level locks, which are fast and flexible but require significant attention for correctness, to higher-level concurrency techniques, which sacrifice some performance to improve ease of use.
+Ease of use comes by either guaranteeing some problems cannot occur (\eg deadlock free), or by offering a more explicit coupling between shared data and critical section.
 For example, the \CC @std::atomic<T>@ offers an easy way to express mutual-exclusion on a restricted set of operations (\eg reading/writing large types atomically).
-Another challenge with low-level locks is composability.
-Locks have restricted composability because it takes careful organizing for multiple locks to be used while preventing deadlocks.
-Easing composability is another feature higher-level mutual-exclusion mechanisms often offer.
-
-
-\subsubsection{Synchronization}
-
-As with mutual-exclusion, low-level synchronization primitives often offer good performance and good flexibility at the cost of ease of use.
-Again, higher-level mechanisms often simplify usage by adding either better coupling between synchronization and data (\eg message passing) or offering a simpler solution to otherwise involved challenges.
+However, a significant challenge with (low-level) locks is composability because it takes careful organization for multiple locks to be used while preventing deadlock.
+Easing composability is another feature higher-level mutual-exclusion mechanisms offer.
+
+
+\subsection{Synchronization}
+
+Synchronization enforces relative ordering of execution, and synchronization tools provide numerous mechanisms to establish these timing relationships.
+Low-level synchronization primitives offer good performance and flexibility at the cost of ease of use.
+Higher-level mechanisms often simplify usage by adding better coupling between synchronization and data (\eg message passing), or offering a simpler solution to otherwise involved challenges, \eg barrier lock.
 As mentioned above, synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}.
-Most of the time, synchronization happens within a critical section, where threads must acquire mutual-exclusion in a certain order.
-However, it may also be desirable to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}.
-Not satisfying this property is called \textbf{barging}.
-For example, where event \textit{X} tries to effect event \textit{Y} but another thread acquires the critical section and emits \textit{Z} before \textit{Y}.
-The classic example is the thread that finishes using a resource and unblocks a thread waiting to use the resource, but the unblocked thread must compete to acquire the resource.
+Often synchronization is used to order access to a critical section, \eg ensuring the next kind of thread to enter a critical section is a reader thread
+If a writer thread is scheduled for next access, but another reader thread acquires the critical section first, the reader has \newterm{barged}.
+Barging can result in staleness/freshness problems, where a reader barges ahead of a write and reads temporally stale data, or a writer barges ahead of another writer overwriting data with a fresh value preventing the previous value from having an opportunity to be read.
 Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs.
-This challenge is often split into two different methods, barging avoidance and barging prevention.
-Algorithms that use flag variables to detect barging threads are said to be using barging avoidance, while algorithms that baton-pass locks~\cite{Andrews89} between threads instead of releasing the locks are said to be using barging prevention.
-
-
-% ======================================================================
-% ======================================================================
+This challenge is often split into two different approaches, barging avoidance and barging prevention.
+Algorithms that allow a barger but divert it until later are avoiding the barger, while algorithms that preclude a barger from entering during synchronization in the critical section prevent the barger completely.
+baton-pass locks~\cite{Andrews89} between threads instead of releasing the locks are said to be using barging prevention.
+
+
 \section{Monitors}
-% ======================================================================
-% ======================================================================
+\label{s:Monitors}
+
 A \textbf{monitor} is a set of routines that ensure mutual-exclusion when accessing shared state.
 More precisely, a monitor is a programming technique that associates mutual-exclusion to routine scopes, as opposed to mutex locks, where mutual-exclusion is defined by lock/release calls independently of any scoping of the calling routine.
@@ -2501,5 +2433,5 @@
 Given these building blocks, it is possible to reproduce all three of the popular paradigms.
 Indeed, \textbf{uthread} is the default paradigm in \CFA.
-However, disabling \textbf{preemption} on the \textbf{cfacluster} means \textbf{cfathread} effectively become \textbf{fiber}.
+However, disabling \textbf{preemption} on a cluster means threads effectively become fibers.
 Since several \textbf{cfacluster} with different scheduling policy can coexist in the same application, this allows \textbf{fiber} and \textbf{uthread} to coexist in the runtime of an application.
 Finally, it is possible to build executors for thread pools from \textbf{uthread} or \textbf{fiber}, which includes specialized jobs like actors~\cite{Actors}.
Index: doc/papers/general/Paper.tex
===================================================================
--- doc/papers/general/Paper.tex	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ doc/papers/general/Paper.tex	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -243,5 +243,5 @@
 Nevertheless, C, first standardized almost forty years ago~\cite{ANSI89:C}, lacks many features that make programming in more modern languages safer and more productive.
 
-\CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language-features to C, while maintaining both source and runtime compatibility with C and a familiar programming model for programmers.
+\CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language-features to C, while maintaining source and runtime compatibility in the familiar C programming model.
 The four key design goals for \CFA~\cite{Bilson03} are:
 (1) The behaviour of standard C code must remain the same when translated by a \CFA compiler as when translated by a C compiler;
@@ -273,5 +273,5 @@
 Starting with a translator versus a compiler makes it easier and faster to generate and debug C object-code rather than intermediate, assembler or machine code.
 The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes.
-At the heart of the translator is the type resolver, which handles the polymorphic routine/type overload-resolution.
+At the heart of the translator is the type resolver, which handles the polymorphic function/type overload-resolution.
 % @plg2[8]% cd cfa-cc/src; cloc libcfa
 % -------------------------------------------------------------------------------
@@ -310,6 +310,6 @@
 
 Finally, it is impossible to describe a programming language without usages before definitions.
-Therefore, syntax and semantics appear before explanations;
-hence, patience is necessary until details are presented.
+Therefore, syntax and semantics appear before explanations, and related work (Section~\ref{s:RelatedWork}) is deferred until \CFA is presented;
+hence, patience is necessary until details are discussed.
 
 
@@ -329,5 +329,5 @@
 \end{quote}
 \vspace{-9pt}
-C already has a limited form of ad-hoc polymorphism in the form of its basic arithmetic operators, which apply to a variety of different types using identical syntax. 
+C already has a limited form of ad-hoc polymorphism in its basic arithmetic operators, which apply to a variety of different types using identical syntax. 
 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable;
 Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C. 
@@ -653,5 +653,5 @@
 }
 \end{cfa}
-Since @pair( T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the fields of both pairs and the arguments to the comparison function match in type.
+Since @pair( T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the members of both pairs and the arguments to the comparison function match in type.
 
 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \newterm{tag-structures}.
@@ -815,5 +815,5 @@
 \subsection{Member Access}
 
-It is also possible to access multiple fields from a single expression using a \newterm{member-access}.
+It is also possible to access multiple members from a single expression using a \newterm{member-access}.
 The result is a single tuple-valued expression whose type is the tuple of the types of the members, \eg:
 \begin{cfa}
@@ -1020,10 +1020,10 @@
 \begin{cfa}
 forall( dtype T0, dtype T1 | sized(T0) | sized(T1) ) struct _tuple2 {
-	T0 field_0;  T1 field_1;					$\C{// generated before the first 2-tuple}$
+	T0 member_0;  T1 member_1;					$\C{// generated before the first 2-tuple}$
 };
 _tuple2(int, int) f() {
 	_tuple2(double, double) x;
 	forall( dtype T0, dtype T1, dtype T2 | sized(T0) | sized(T1) | sized(T2) ) struct _tuple3 {
-		T0 field_0;  T1 field_1;  T2 field_2;	$\C{// generated before the first 3-tuple}$
+		T0 member_0;  T1 member_1;  T2 member_2;	$\C{// generated before the first 3-tuple}$
 	};
 	_tuple3(int, double, int) y;
@@ -1033,5 +1033,5 @@
 
 \begin{comment}
-Since tuples are essentially structures, tuple indexing expressions are just field accesses:
+Since tuples are essentially structures, tuple indexing expressions are just member accesses:
 \begin{cfa}
 void f(int, [double, char]);
@@ -1047,9 +1047,9 @@
 _tuple2(int, double) x;
 
-x.field_0+x.field_1;
-printf("%d %g\n", x.field_0, x.field_1);
-f(x.field_0, (_tuple2){ x.field_1, 'z' });
-\end{cfa}
-Note that due to flattening, @x@ used in the argument position is converted into the list of its fields.
+x.member_0+x.member_1;
+printf("%d %g\n", x.member_0, x.member_1);
+f(x.member_0, (_tuple2){ x.member_1, 'z' });
+\end{cfa}
+Note that due to flattening, @x@ used in the argument position is converted into the list of its members.
 In the call to @f@, the second and third argument components are structured into a tuple argument.
 Similarly, tuple member expressions are recursively expanded into a list of member access expressions.
@@ -1083,5 +1083,5 @@
 
 The various kinds of tuple assignment, constructors, and destructors generate GNU C statement expressions.
-A variable is generated to store the value produced by a statement expression, since its fields may need to be constructed with a non-trivial constructor and it may need to be referred to multiple time, \eg in a unique expression.
+A variable is generated to store the value produced by a statement expression, since its members may need to be constructed with a non-trivial constructor and it may need to be referred to multiple time, \eg in a unique expression.
 The use of statement expressions allows the translator to arbitrarily generate additional temporary variables as needed, but binds the implementation to a non-standard extension of the C language.
 However, there are other places where the \CFA translator makes use of GNU C extensions, such as its use of nested functions, so this restriction is not new.
@@ -1493,5 +1493,5 @@
 
 Heterogeneous data is often aggregated into a structure/union.
-To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate field-qualification by opening a scope containing the field identifiers.
+To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate member-qualification by opening a scope containing the member identifiers.
 \begin{cquote}
 \vspace*{-\baselineskip}%???
@@ -1530,12 +1530,12 @@
 The type must be an aggregate type.
 (Enumerations are already opened.)
-The object is the implicit qualifier for the open structure-fields.
+The object is the implicit qualifier for the open structure-members.
 
 All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right.
-The difference between parallel and nesting occurs for fields with the same name and type:
-\begin{cfa}
-struct S { int `i`; int j; double m; } s, w;
+The difference between parallel and nesting occurs for members with the same name and type:
+\begin{cfa}
+struct S { int `i`; int j; double m; } s, w;	$\C{// member i has same type in structure types S and T}$
 struct T { int `i`; int k; int m; } t, w;
-with ( s, t ) {
+with ( s, t ) {								$\C{// open structure variables s and t in parallel}$
 	j + k;									$\C{// unambiguous, s.j + t.k}$
 	m = 5.0;								$\C{// unambiguous, s.m = 5.0}$
@@ -1549,5 +1549,5 @@
 For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@ is ambiguous without qualification;
 for nested semantics, @t.i@ hides @s.i@, so @i@ implies @t.i@.
-\CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
+\CFA's ability to overload variables means members with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
 Qualification or a cast is used to disambiguate.
 
@@ -1555,5 +1555,5 @@
 \begin{cfa}
 void ?{}( S & s, int i ) with ( s ) {		$\C{// constructor}$
-	`s.i = i;`  j = 3;  m = 5.5;			$\C{// initialize fields}$
+	`s.i = i;`  j = 3;  m = 5.5;			$\C{// initialize members}$
 }
 \end{cfa}
@@ -1659,5 +1659,5 @@
 \lstMakeShortInline@%
 \end{cquote}
-The only exception is bit field specification, which always appear to the right of the base type.
+The only exception is bit-field specification, which always appear to the right of the base type.
 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a function parameter.
 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
@@ -1715,5 +1715,5 @@
 // pointer to array of 5 doubles
 
-// common bit field syntax
+// common bit-field syntax
 
 
@@ -1911,8 +1911,8 @@
 \subsection{Type Nesting}
 
-Nested types provide a mechanism to organize associated types and refactor a subset of fields into a named aggregate (\eg sub-aggregates @name@, @address@, @department@, within aggregate @employe@).
+Nested types provide a mechanism to organize associated types and refactor a subset of members into a named aggregate (\eg sub-aggregates @name@, @address@, @department@, within aggregate @employe@).
 Java nested types are dynamic (apply to objects), \CC are static (apply to the \lstinline[language=C++]@class@), and C hoists (refactors) nested types into the enclosing scope, meaning there is no need for type qualification.
 Since \CFA in not object-oriented, adopting dynamic scoping does not make sense;
-instead \CFA adopts \CC static nesting, using the field-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}).
+instead \CFA adopts \CC static nesting, using the member-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}).
 \begin{figure}
 \centering
@@ -2005,6 +2005,6 @@
 Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not deallocate.}.
 \begin{cfa}
-struct VLA { int len, * data; };			$\C{// variable length array of integers}$
-void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  $\C{// default constructor}$
+struct VLA { int size, * data; };			$\C{// variable length array of integers}$
+void ?{}( VLA & vla ) with ( vla ) { size = 10;  data = alloc( size ); }  $\C{// default constructor}$
 void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
 {
@@ -2013,5 +2013,5 @@
 \end{cfa}
 @VLA@ is a \newterm{managed type}\footnote{
-A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a field of a managed type. 
+A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a member of a managed type. 
 A managed type is implicitly constructed at allocation and destructed at deallocation to ensure proper interaction with runtime resources, in this case, the @data@ array in the heap. 
 For details of the code-generation placement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}.
@@ -2019,9 +2019,9 @@
 \CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
 \begin{cfa}
-void ?{}( VLA & vla, int size, char fill ) with ( vla ) {  $\C{// initialization}$
-	len = size;  data = alloc( len, fill );
+void ?{}( VLA & vla, int size, char fill = '\0' ) {  $\C{// initialization}$
+	vla.[ size, data ] = [ size, alloc( size, fill ) ];
 }
 void ?{}( VLA & vla, VLA other ) {			$\C{// copy, shallow}$
-	vla.len = other.len;  vla.data = other.data;
+	vla = other;
 }
 \end{cfa}
@@ -2036,5 +2036,5 @@
 
 \CFA constructors may be explicitly called, like Java, and destructors may be explicitly called, like \CC.
-Explicit calls to constructors double as a \CC-style \emph{placement syntax}, useful for construction of member fields in user-defined constructors and reuse of existing storage allocations.
+Explicit calls to constructors double as a \CC-style \emph{placement syntax}, useful for construction of members in user-defined constructors and reuse of existing storage allocations.
 Like the other operators in \CFA, there is a concise syntax for constructor/destructor function calls:
 \begin{cfa}
@@ -2048,6 +2048,5 @@
 	y{ x };									$\C{// reallocate y, points to x}$
 	x{};									$\C{// reallocate x, not pointing to y}$
-	//  ^z{};  ^y{};  ^x{};
-}
+}	//  ^z{};  ^y{};  ^x{};
 \end{cfa}
 
@@ -2060,7 +2059,7 @@
 For compatibility with C, a copy constructor from the first union member type is also defined.
 For @struct@ types, each of the four functions are implicitly defined to call their corresponding functions on each member of the struct. 
-To better simulate the behaviour of C initializers, a set of \newterm{field constructors} is also generated for structures. 
+To better simulate the behaviour of C initializers, a set of \newterm{member constructors} is also generated for structures. 
 A constructor is generated for each non-empty prefix of a structure's member-list to copy-construct the members passed as parameters and default-construct the remaining members.
-To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all field constructors for that type are hidden from expression resolution;
+To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all member constructors for that type are hidden from expression resolution;
 similarly, the generated default constructor is hidden upon declaration of any constructor. 
 These semantics closely mirror the rule for implicit declaration of constructors in \CC\cite[p.~186]{ANSI98:C++}.
@@ -2740,4 +2739,5 @@
 
 \section{Related Work}
+\label{s:RelatedWork}
 
 
@@ -2793,5 +2793,5 @@
 C provides variadic functions through @va_list@ objects, but the programmer is responsible for managing the number of arguments and their types, so the mechanism is type unsafe.
 KW-C~\cite{Buhr94a}, a predecessor of \CFA, introduced tuples to C as an extension of the C syntax, taking much of its inspiration from SETL.
-The main contributions of that work were adding MRVF, tuple mass and multiple assignment, and record-field access.
+The main contributions of that work were adding MRVF, tuple mass and multiple assignment, and record-member access.
 \CCeleven introduced @std::tuple@ as a library variadic template structure.
 Tuples are a generalization of @std::pair@, in that they allow for arbitrary length, fixed-size aggregation of heterogeneous values.
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/CodeGen/CodeGenerator.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -119,10 +119,11 @@
 
 	string CodeGenerator::mangleName( DeclarationWithType * decl ) {
-		if ( pretty ) return decl->get_name();
-		if ( decl->get_mangleName() != "" ) {
+		// GCC builtins should always be printed unmangled
+		if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name;
+		if ( decl->mangleName != "" ) {
 			// need to incorporate scope level in order to differentiate names for destructors
 			return decl->get_scopedMangleName();
 		} else {
-			return decl->get_name();
+			return decl->name;
 		} // if
 	}
Index: src/Common/Heap.cc
===================================================================
--- src/Common/Heap.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/Common/Heap.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -30,10 +30,12 @@
 #else
 	struct StatBlock {
-		const char * name = nullptr;
-		size_t mallocs    = 0;
-		size_t frees      = 0;
+		const char * name  = nullptr;	///< Name of this pass
+		size_t mallocs     = 0;			///< Allocations in this pass
+		size_t frees       = 0;			///< Frees in this pass
+		size_t n_allocs    = 0;			///< Current number of live allocations
+		size_t peak_allocs = 0;			///< Peak number of live allocations this pass
 	};
 
-	StatBlock    passes[100] = {{ "Pre-Parse", 0, 0 }};
+	StatBlock    passes[100] = {{ "Pre-Parse", 0, 0, 0, 0 }};
 	const size_t passes_size = sizeof(passes) / sizeof(passes[0]);
 	size_t       passes_cnt = 1;
@@ -43,4 +45,7 @@
 		passes[passes_cnt].mallocs = 0;
 		passes[passes_cnt].frees   = 0;
+		passes[passes_cnt].n_allocs 
+			= passes[passes_cnt].peak_allocs 
+			= passes[passes_cnt-1].n_allocs;
 		passes_cnt++;
 
@@ -55,10 +60,11 @@
 	}
 
-	void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees) {
+	void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees, size_t overall_peak) {
 		std::cerr << std::setw(nc) << stat.name;
 		std::cerr << " | ";
 
-		print(stat.mallocs, total_mallocs);
-		print(stat.frees  , total_frees  );
+		print(stat.mallocs,     total_mallocs);
+		print(stat.frees,       total_frees  );
+		print(stat.peak_allocs, overall_peak );
 		std::cerr << "\n";
 	}
@@ -75,10 +81,12 @@
 		size_t total_mallocs = 0;
 		size_t total_frees   = 0;
+		size_t overall_peak  = 0;
 		for(size_t i = 0; i < passes_cnt; i++) {
 			nc = std::max(nc, std::strlen(passes[i].name));
 			total_mallocs += passes[i].mallocs;
 			total_frees   += passes[i].frees;
-		}
-		size_t nct = nc + 44;
+			overall_peak = std::max(overall_peak, passes[i].peak_allocs);
+		}
+		size_t nct = nc + 65;
 
 		const char * const title = "Heap Usage Statistic";
@@ -88,12 +96,13 @@
 		print('-', nct);
 		std::cerr << std::setw(nc) << "Pass";
-		std::cerr << " |       Malloc Count |         Free Count |" << std::endl;
+		std::cerr << " |       Malloc Count |         Free Count |        Peak Allocs |" << std::endl;
 
 		print('-', nct);
 		for(size_t i = 0; i < passes_cnt; i++) {
-			print(passes[i], nc, total_mallocs, total_frees);
+			print(passes[i], nc, total_mallocs, total_frees, overall_peak);
 		}
 		print('-', nct);
-		print({"Sum", total_mallocs, total_frees}, nc, total_mallocs, total_frees);
+		print({"Sum", total_mallocs, total_frees, 0, overall_peak}, 
+			nc, total_mallocs, total_frees, overall_peak);
 
 	}
@@ -158,5 +167,10 @@
 		void * malloc( size_t size ) {
 			static auto __malloc = reinterpret_cast<void * (*)(size_t)>(interpose_symbol( "malloc", nullptr ));
-			if( passes_cnt > 0 ) passes[passes_cnt - 1].mallocs++;
+			if( passes_cnt > 0 ) {
+				passes[passes_cnt - 1].mallocs++;
+				passes[passes_cnt - 1].n_allocs++;
+				passes[passes_cnt - 1].peak_allocs 
+					= std::max(passes[passes_cnt - 1].peak_allocs, passes[passes_cnt - 1].n_allocs);
+			}
 			return __malloc( size );
 		}
@@ -164,5 +178,8 @@
 		void free( void * ptr ) {
 			static auto __free = reinterpret_cast<void   (*)(void *)>(interpose_symbol( "free", nullptr ));
-			if( passes_cnt > 0 ) passes[passes_cnt - 1].frees++;
+			if( passes_cnt > 0 ) {
+				passes[passes_cnt - 1].frees++;
+				passes[passes_cnt - 1].n_allocs--;
+			}
 			return __free( ptr );
 		}
@@ -170,5 +187,10 @@
 		void * calloc( size_t nelem, size_t size ) {
 			static auto __calloc = reinterpret_cast<void * (*)(size_t, size_t)>(interpose_symbol( "calloc", nullptr ));
-			if( passes_cnt > 0 ) passes[passes_cnt - 1].mallocs++;
+			if( passes_cnt > 0 ) {
+				passes[passes_cnt - 1].mallocs++;
+				passes[passes_cnt - 1].n_allocs++;
+				passes[passes_cnt - 1].peak_allocs 
+					= std::max(passes[passes_cnt - 1].peak_allocs, passes[passes_cnt - 1].n_allocs);
+			}
 			return __calloc( nelem, size );
 		}
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/Concurrency/Keywords.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -191,5 +191,5 @@
 		void postvisit(   StructDecl * decl );
 
-		std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
+		std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
 		void validate( DeclarationWithType * );
 		void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
@@ -441,8 +441,9 @@
 	void MutexKeyword::postvisit(FunctionDecl* decl) {
 
-		std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
+		bool first = false;
+		std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first );
 		if( mutexArgs.empty() ) return;
 
-		if( CodeGen::isConstructor(decl->name) ) SemanticError( decl, "constructors cannot have mutex parameters" );
+		if( CodeGen::isConstructor(decl->name) && first ) SemanticError( decl, "constructors cannot have mutex parameters" );
 
 		bool isDtor = CodeGen::isDestructor( decl->name );
@@ -484,11 +485,15 @@
 	}
 
-	std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
+	std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl, bool & first ) {
 		std::list<DeclarationWithType*> mutexArgs;
 
+		bool once = true;
 		for( auto arg : decl->get_functionType()->get_parameters()) {
 			//Find mutex arguments
 			Type* ty = arg->get_type();
 			if( ! ty->get_mutex() ) continue;
+
+			if(once) {first = true;}
+			once = false;
 
 			//Append it to the list
Index: src/Parser/LinkageSpec.h
===================================================================
--- src/Parser/LinkageSpec.h	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/Parser/LinkageSpec.h	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -27,6 +27,7 @@
 		Overrideable = 1 << 2,
 		Builtin = 1 << 3,
+		GccBuiltin = 1 << 4,
 
-		NoOfSpecs = 1 << 4,
+		NoOfSpecs = 1 << 5,
 	};
 
@@ -38,4 +39,5 @@
 			bool is_overridable : 1;
 			bool is_builtin : 1;
+			bool is_gcc_builtin : 1;
 		};
 		constexpr Spec( unsigned int val ) : val( val ) {}
@@ -61,4 +63,5 @@
 	inline bool isOverridable( Spec spec ) { return spec.is_overridable; }
 	inline bool isBuiltin( Spec spec ) { return spec.is_builtin; }
+	inline bool isGccBuiltin( Spec spec ) { return spec.is_gcc_builtin; }
 
 	// Pre-defined flag combinations:
@@ -72,5 +75,5 @@
 	constexpr Spec const AutoGen = { Mangle | Generate | Overrideable };
 	// gcc internal
-	constexpr Spec const Compiler = { Builtin };
+	constexpr Spec const Compiler = { Mangle | Builtin | GccBuiltin };
 	// mangled builtins
 	constexpr Spec const BuiltinCFA = { Mangle | Generate | Builtin };
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/Parser/TypeData.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -575,5 +575,5 @@
 
 	  case DeclarationNode::Int128:
-		ret = td->signedness == 1 ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
+		ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
 		if ( td->length != DeclarationNode::NoLength ) {
 			genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
@@ -599,5 +599,5 @@
 			genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
 		} // if
-		if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) {
+		if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) {
 			genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
 		} // if
@@ -605,4 +605,13 @@
 			const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
 		} // if
+
+		if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
+			if ( td->complextype != DeclarationNode::NoComplexType ) {
+				genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
+			}
+			if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
+			else ret = BasicType::Float128;
+			break;
+		}
 
 		ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/Parser/parser.yy	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 22 08:41:57 2018
-// Update Count     : 3353
+// Last Modified On : Mon May 28 17:01:36 2018
+// Update Count     : 3383
 //
 
@@ -326,5 +326,5 @@
 %type<decl> cfa_identifier_parameter_declarator_tuple cfa_identifier_parameter_ptr
 
-%type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_type_list_opt
+%type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_ellipsis_list_opt
 
 %type<decl> cfa_typedef_declaration cfa_variable_declaration cfa_variable_specifier
@@ -852,10 +852,10 @@
 //	'[' ']'
 //		{ $$ = new ExpressionNode( build_tuple() ); }
-//	'[' push assignment_expression pop ']'
+//	| '[' push assignment_expression pop ']'
 //		{ $$ = new ExpressionNode( build_tuple( $3 ) ); }
-	'[' ',' tuple_expression_list ']'
-		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
-	| '[' assignment_expression ',' tuple_expression_list ']'
-		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$2->set_last( $4 ) ) ); }
+	'[' push ',' tuple_expression_list pop ']'
+		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $4 ) ) ); }
+	| '[' push assignment_expression ',' tuple_expression_list pop ']'
+		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $5 ) ) ); }
 	;
 
@@ -883,5 +883,5 @@
 	labeled_statement
 	| compound_statement
-	| expression_statement						{ $$ = $1; }
+	| expression_statement
 	| selection_statement
 	| iteration_statement
@@ -1200,13 +1200,9 @@
 	type_specifier_nobody
 	| type_specifier_nobody declarator
-		{
-			$$ = $2->addType( $1 );
-		}
+		{ $$ = $2->addType( $1 ); }
 	| type_specifier_nobody variable_abstract_declarator
 		{ $$ = $2->addType( $1 ); }
 	| cfa_abstract_declarator_tuple no_attr_identifier	// CFA
-		{
-			$$ = $1->addName( $2 );
-		}
+		{ $$ = $1->addName( $2 ); }
 	| cfa_abstract_declarator_tuple						// CFA
 	;
@@ -1286,5 +1282,5 @@
 
 declaration_list_opt:									// used at beginning of switch statement
-	pop
+	pop	// empty
 		{ $$ = nullptr; }
 	| declaration_list
@@ -1321,6 +1317,6 @@
 
 local_label_list:										// GCC, local label
-	no_attr_identifier_or_type_name				{}
-	| local_label_list ',' no_attr_identifier_or_type_name {}
+	no_attr_identifier_or_type_name
+	| local_label_list ',' no_attr_identifier_or_type_name
 	;
 
@@ -1385,24 +1381,24 @@
 	| declaration_qualifier_list type_qualifier_list cfa_function_specifier
 		{ $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); }
-	| cfa_function_declaration ',' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
+	| cfa_function_declaration ',' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
 		{
 			// Append the return type at the start (left-hand-side) to each identifier in the list.
 			DeclarationNode * ret = new DeclarationNode;
 			ret->type = maybeClone( $1->type->base );
-			$$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $5, nullptr ) );
+			$$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $6, nullptr ) );
 		}
 	;
 
 cfa_function_specifier:									// CFA
-//	'[' ']' identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')' // S/R conflict
+//	'[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
 //		{
 //			$$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
 //		}
-//	'[' ']' identifier '(' push cfa_parameter_type_list_opt pop ')'
+//	'[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
 //		{
 //			typedefTable.setNextIdentifier( *$5 );
 //			$$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
 //		}
-//	| '[' ']' TYPEDEFname '(' push cfa_parameter_type_list_opt pop ')'
+//	| '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
 //		{
 //			typedefTable.setNextIdentifier( *$5 );
@@ -1412,23 +1408,22 @@
 		// identifier_or_type_name must be broken apart because of the sequence:
 		//
-		//   '[' ']' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
+		//   '[' ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')'
 		//   '[' ']' type_specifier
 		//
 		// type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
 		// flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
-	cfa_abstract_tuple identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
+	cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
 		// To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
-		{ $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
-	| cfa_function_return identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
-		{ $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
+		{ $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
+	| cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
 	;
 
 cfa_function_return:									// CFA
-	'[' cfa_parameter_list ']'
-		{ $$ = DeclarationNode::newTuple( $2 ); }
-	| '[' cfa_parameter_list ',' cfa_abstract_parameter_list ']'
-		// To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the
-		// ']'.
-		{ $$ = DeclarationNode::newTuple( $2->appendList( $4 ) ); }
+	'[' push cfa_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
+	| '[' push cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ']'
+		// To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the ']'.
+		{ $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
 	;
 
@@ -1604,13 +1599,6 @@
 
 forall:
-	FORALL '('
-		{
-			typedefTable.enterScope();
-		}
-	  type_parameter_list ')'							// CFA
-		{
-			typedefTable.leaveScope();
-			$$ = DeclarationNode::newForall( $4 );
-		}
+	FORALL '(' push type_parameter_list pop ')'					// CFA
+		{ $$ = DeclarationNode::newForall( $4 ); }
 	;
 
@@ -1980,5 +1968,5 @@
 	;
 
-cfa_parameter_type_list_opt:							// CFA, abstract + real
+cfa_parameter_ellipsis_list_opt:							// CFA, abstract + real
 	// empty
 		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
@@ -1987,9 +1975,9 @@
 	| cfa_abstract_parameter_list
 	| cfa_parameter_list
-	| cfa_parameter_list ',' cfa_abstract_parameter_list
-		{ $$ = $1->appendList( $3 ); }
-	| cfa_abstract_parameter_list ',' ELLIPSIS
+	| cfa_parameter_list pop ',' push cfa_abstract_parameter_list
+		{ $$ = $1->appendList( $5 ); }
+	| cfa_abstract_parameter_list pop ',' push ELLIPSIS
 		{ $$ = $1->addVarArgs(); }
-	| cfa_parameter_list ',' ELLIPSIS
+	| cfa_parameter_list pop ',' push ELLIPSIS
 		{ $$ = $1->addVarArgs(); }
 	;
@@ -1999,16 +1987,16 @@
 		// factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'.
 	cfa_parameter_declaration
-	| cfa_abstract_parameter_list ',' cfa_parameter_declaration
-		{ $$ = $1->appendList( $3 ); }
-	| cfa_parameter_list ',' cfa_parameter_declaration
-		{ $$ = $1->appendList( $3 ); }
-	| cfa_parameter_list ',' cfa_abstract_parameter_list ',' cfa_parameter_declaration
-		{ $$ = $1->appendList( $3 )->appendList( $5 ); }
+	| cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| cfa_parameter_list pop ',' push cfa_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
+		{ $$ = $1->appendList( $5 )->appendList( $9 ); }
 	;
 
 cfa_abstract_parameter_list:							// CFA, new & old style abstract
 	cfa_abstract_parameter_declaration
-	| cfa_abstract_parameter_list ',' cfa_abstract_parameter_declaration
-		{ $$ = $1->appendList( $3 ); }
+	| cfa_abstract_parameter_list pop ',' push cfa_abstract_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
 	;
 
@@ -2159,13 +2147,13 @@
 	'.' no_attr_identifier								// C99, field name
 		{ $$ = new ExpressionNode( build_varref( $2 ) ); }
-	| '[' assignment_expression ']'						// C99, single array element
+	| '[' push assignment_expression pop ']'			// C99, single array element
 		// assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
-		{ $$ = $2; }
-	| '[' subrange ']'									// CFA, multiple array elements
-		{ $$ = $2; }
-	| '[' constant_expression ELLIPSIS constant_expression ']' // GCC, multiple array elements
-		{ $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $2 ), maybeMoveBuild< Expression >( $4 ) ) ); }
-	| '.' '[' field_list ']'							// CFA, tuple field selector
 		{ $$ = $3; }
+	| '[' push subrange pop ']'							// CFA, multiple array elements
+		{ $$ = $3; }
+	| '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
+		{ $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); }
+	| '.' '[' push field_list pop ']'					// CFA, tuple field selector
+		{ $$ = $4; }
 	;
 
@@ -2238,7 +2226,7 @@
 	'|' no_attr_identifier_or_type_name '(' type_list ')'
 		{ $$ = DeclarationNode::newTraitUse( $2, $4 ); }
-	| '|' '{' push trait_declaration_list '}'
+	| '|' '{' push trait_declaration_list pop '}'
 		{ $$ = $4; }
-	| '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}' '(' type_list ')'
+	| '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')'
 		{ SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
 	;
@@ -2286,7 +2274,5 @@
 	TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}'
 		{ $$ = DeclarationNode::newTrait( $2, $5, 0 ); }
-	| TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{'
-		{ typedefTable.enterScope(); }
-	  trait_declaration_list '}'
+	| TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}'
 		{ $$ = DeclarationNode::newTrait( $2, $5, $10 ); }
 	;
@@ -2294,18 +2280,16 @@
 trait_declaration_list:									// CFA
 	trait_declaration
-	| trait_declaration_list push trait_declaration
-		{ $$ = $1->appendList( $3 ); }
+	| trait_declaration_list pop push trait_declaration
+		{ $$ = $1->appendList( $4 ); }
 	;
 
 trait_declaration:										// CFA
-	cfa_trait_declaring_list pop ';'
-	| trait_declaring_list pop ';'
+	cfa_trait_declaring_list ';'
+	| trait_declaring_list ';'
 	;
 
 cfa_trait_declaring_list:								// CFA
 	cfa_variable_specifier
-		{ $$ = $1; }
 	| cfa_function_specifier
-		{ $$ = $1; }
 	| cfa_trait_declaring_list pop ',' push identifier_or_type_name
 		{ $$ = $1->appendList( $1->cloneType( $5 ) ); }
@@ -2366,7 +2350,5 @@
 		}
 	| type_qualifier_list
-		{
-			if ( $1->type->forall ) xxx = forall = true; // remember generic type
-		}
+		{ if ( $1->type->forall ) xxx = forall = true; } // remember generic type
 	  push '{' external_definition_list '}'				// CFA, namespace
 		{
@@ -2381,7 +2363,5 @@
 		}
 	| declaration_qualifier_list
-		{
-			if ( $1->type->forall ) xxx = forall = true; // remember generic type
-		}
+		{ if ( $1->type->forall ) xxx = forall = true; } // remember generic type
 	  push '{' external_definition_list '}'				// CFA, namespace
 		{
@@ -2423,13 +2403,7 @@
 		// declaration must still have a type_specifier.  OBSOLESCENT (see 1)
 	| function_declarator compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $1->addFunctionBody( $2 );
-		}
+		{ $$ = $1->addFunctionBody( $2 ); }
 	| KR_function_declarator KR_declaration_list_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 );
-		}
+		{ $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 ); }
 	;
 
@@ -2444,5 +2418,4 @@
 	cfa_function_declaration with_clause_opt compound_statement	// CFA
 		{
-			typedefTable.leaveScope();
 			// Add the function body to the last identifier in the function definition list, i.e., foo3:
 			//   [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; }
@@ -2453,5 +2426,4 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
 		}
@@ -2459,25 +2431,15 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
 		}
 		// handles default int return type, OBSOLESCENT (see 1)
 	| type_qualifier_list function_declarator with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list function_declarator with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 );
-		}
+		{ $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 ); }
 
 		// Old-style K&R function definition, OBSOLESCENT (see 4)
@@ -2485,25 +2447,15 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.leaveScope();
 			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 );
 		}
 		// handles default int return type, OBSOLESCENT (see 1)
 	| type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 );
-		}
+		{ $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); }
 	;
 
@@ -2702,6 +2654,6 @@
 	paren_identifier '(' identifier_list ')'			// function_declarator handles empty parameter
 		{ $$ = $1->addIdList( $3 ); }
-	| '(' KR_function_ptr ')' '(' parameter_type_list_opt ')'
-		{ $$ = $2->addParamList( $5 ); }
+	| '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' KR_function_no_ptr ')'						// redundant parenthesis
 		{ $$ = $2; }
@@ -2821,8 +2773,8 @@
 
 identifier_parameter_function:
-	paren_identifier '(' parameter_type_list_opt ')'	// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $1->addParamList( $3 ); }
-	| '(' identifier_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' identifier_parameter_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -2874,8 +2826,8 @@
 
 type_parameter_function:
-	typedef '(' parameter_type_list_opt ')'				// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $1->addParamList( $3 ); }
-	| '(' type_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	typedef '(' push parameter_type_list_opt pop ')'	// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	;
 
@@ -2924,8 +2876,8 @@
 
 abstract_function:
-	'(' parameter_type_list_opt ')'						// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
-	| '(' abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	'(' push parameter_type_list_opt pop ')'			// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
+	| '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' abstract_function ')'							// redundant parenthesis
 		{ $$ = $2; }
@@ -2942,11 +2894,11 @@
 
 multi_array_dimension:
-	'[' assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $2, 0, false ); }
-	| '[' '*' ']'										// C99
+	'[' push assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $3, 0, false ); }
+	| '[' push '*' pop ']'								// C99
 		{ $$ = DeclarationNode::newVarArray( 0 ); }
-	| multi_array_dimension '[' assignment_expression ']'
-		{ $$ = $1->addArray( DeclarationNode::newArray( $3, 0, false ) ); }
-	| multi_array_dimension '[' '*' ']'					// C99
+	| multi_array_dimension '[' push assignment_expression pop ']'
+		{ $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
+	| multi_array_dimension '[' push '*' pop ']'		// C99
 		{ $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
 	;
@@ -3015,8 +2967,8 @@
 
 abstract_parameter_function:
-	'(' parameter_type_list_opt ')'						// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
-	| '(' abstract_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	'(' push parameter_type_list_opt pop ')'			// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
+	| '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' abstract_parameter_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -3039,16 +2991,16 @@
 	'[' ']'
 		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
-	// multi_array_dimension handles the '[' '*' ']' case
-	| '[' type_qualifier_list '*' ']'					// remaining C99
-		{ $$ = DeclarationNode::newVarArray( $2 ); }
-	| '[' type_qualifier_list ']'
-		{ $$ = DeclarationNode::newArray( 0, $2, false ); }
-	// multi_array_dimension handles the '[' assignment_expression ']' case
-	| '[' type_qualifier_list assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $3, $2, false ); }
-	| '[' STATIC type_qualifier_list_opt assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
-	| '[' type_qualifier_list STATIC assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $4, $2, true ); }
+		// multi_array_dimension handles the '[' '*' ']' case
+	| '[' push type_qualifier_list '*' pop ']'			// remaining C99
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list pop ']'
+		{ $$ = DeclarationNode::newArray( 0, $3, false ); }
+		// multi_array_dimension handles the '[' assignment_expression ']' case
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4, true ); }
+	| '[' push type_qualifier_list STATIC assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $3, true ); }
 	;
 
@@ -3094,6 +3046,6 @@
 
 variable_abstract_function:
-	'(' variable_abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	'(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' variable_abstract_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -3158,15 +3110,15 @@
 
 cfa_array_parameter_1st_dimension:
-	'[' type_qualifier_list '*' ']'						// remaining C99
-		{ $$ = DeclarationNode::newVarArray( $2 ); }
-	| '[' type_qualifier_list assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $3, $2, false ); }
-	| '[' declaration_qualifier_list assignment_expression ']'
+	'[' push type_qualifier_list '*' pop ']'			// remaining C99
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push declaration_qualifier_list assignment_expression pop ']'
 		// declaration_qualifier_list must be used because of shift/reduce conflict with
 		// assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot
 		// appear in this context.
-		{ $$ = DeclarationNode::newArray( $3, $2, true ); }
-	| '[' declaration_qualifier_list type_qualifier_list assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $4, $3->addQualifiers( $3 ), true ); }
+		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
+	| '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
 	;
 
@@ -3180,5 +3132,5 @@
 //
 //		cfa_abstract_tuple identifier_or_type_name
-//		'[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
+//		'[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')'
 //
 // since a function return type can be syntactically identical to a tuple type:
@@ -3237,15 +3189,19 @@
 
 cfa_abstract_tuple:										// CFA
-	'[' cfa_abstract_parameter_list ']'
-		{ $$ = DeclarationNode::newTuple( $2 ); }
+	'[' push cfa_abstract_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
+	| '[' push type_specifier_nobody ELLIPSIS ']'
+		{ SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; }
+	| '[' push type_specifier_nobody ELLIPSIS constant_expression ']'
+		{ SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; }
 	;
 
 cfa_abstract_function:									// CFA
-//	'[' ']' '(' cfa_parameter_type_list_opt ')'
+//	'[' ']' '(' cfa_parameter_ellipsis_list_opt ')'
 //		{ $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }
-	cfa_abstract_tuple '(' cfa_parameter_type_list_opt ')'
-		{ $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
-	| cfa_function_return '(' cfa_parameter_type_list_opt ')'
-		{ $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
+	cfa_abstract_tuple '(' push cfa_parameter_ellipsis_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
+	| cfa_function_return '(' push cfa_parameter_ellipsis_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
 	;
 
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/ResolvExpr/CommonType.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -176,31 +176,37 @@
 	}
 
-	static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
+	static const BasicType::Kind combinedType[][ BasicType::NUMBER_OF_BASIC_TYPES ] =
 	{
-/* 		Bool		Char	SignedChar	UnsignedChar	ShortSignedInt	ShortUnsignedInt	SignedInt	UnsignedInt	LongSignedInt	LongUnsignedInt	LongLongSignedInt	LongLongUnsignedInt	Float	Double	LongDouble	FloatComplex	DoubleComplex	LongDoubleComplex	FloatImaginary	DoubleImaginary	LongDoubleImaginary   SignedInt128   UnsignedInt128 */
-		/* Bool */ 	{ BasicType::Bool,		BasicType::Char,	BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* Char */ 	{ BasicType::Char,		BasicType::Char,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* SignedChar */ 	{ BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* UnsignedChar */ 	{ BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* ShortSignedInt */ 	{ BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* ShortUnsignedInt */ 	{ BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* SignedInt */ 	{ BasicType::SignedInt,		BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* UnsignedInt */ 	{ BasicType::UnsignedInt,		BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* LongSignedInt */ 	{ BasicType::LongSignedInt,		BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* LongUnsignedInt */ 	{ BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* LongLongSignedInt */ 	{ BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* LongLongUnsignedInt */ 	{ BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* Float */ 	{ BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::Float,	BasicType::Float, },
-		/* Double */ 	{ BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::LongDouble,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::Double,	BasicType::Double, },
-		/* LongDouble */ 	{ BasicType::LongDouble,		BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDouble,	BasicType::LongDouble, },
-		/* FloatComplex */ 	{ BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::FloatComplex, },
-		/* DoubleComplex */ 	{ BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex, },
-		/* LongDoubleComplex */ 	{ BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex, },
-		/* FloatImaginary */ 	{ BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatImaginary,	BasicType::DoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::FloatImaginary,	BasicType::FloatImaginary, },
-		/* DoubleImaginary */ 	{ BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleImaginary,	BasicType::DoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::DoubleImaginary,	BasicType::DoubleImaginary, },
-		/* LongDoubleImaginary */ 	{ BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::LongDoubleImaginary },
-		/* SignedInt128 */ 	{ BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, },
-		/* UnsignedInt128 */ 	{ BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128, },
+/* 		Bool		Char	SignedChar	UnsignedChar	ShortSignedInt	ShortUnsignedInt	SignedInt	UnsignedInt	LongSignedInt	LongUnsignedInt	LongLongSignedInt	LongLongUnsignedInt	Float	Double	LongDouble	FloatComplex	DoubleComplex	LongDoubleComplex	FloatImaginary	DoubleImaginary	LongDoubleImaginary   SignedInt128   UnsignedInt128   Float80   Float128 */
+		/* Bool */ 	{ BasicType::Bool,		BasicType::Char,	BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* Char */ 	{ BasicType::Char,		BasicType::Char,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* SignedChar */ 	{ BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* UnsignedChar */ 	{ BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* ShortSignedInt */ 	{ BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* ShortUnsignedInt */ 	{ BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* SignedInt */ 	{ BasicType::SignedInt,		BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* UnsignedInt */ 	{ BasicType::UnsignedInt,		BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* LongSignedInt */ 	{ BasicType::LongSignedInt,		BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* LongUnsignedInt */ 	{ BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* LongLongSignedInt */ 	{ BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* LongLongUnsignedInt */ 	{ BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
+		/* Float */ 	{ BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::Float,	BasicType::Float, BasicType::Float80, BasicType::Float128 },
+		/* Double */ 	{ BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::LongDouble,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::Double,	BasicType::Double, BasicType::Float80, BasicType::Float128 },
+		/* LongDouble */ 	{ BasicType::LongDouble,		BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDouble,	BasicType::LongDouble, BasicType::BasicType::LongDouble, BasicType::Float128 },
+		/* FloatComplex */ 	{ BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::FloatComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, },
+		/* DoubleComplex */ 	{ BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex },
+		/* LongDoubleComplex */ 	{ BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, },
+		/* FloatImaginary */ 	{ BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatImaginary,	BasicType::DoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::FloatImaginary,	BasicType::FloatImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
+		/* DoubleImaginary */ 	{ BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleImaginary,	BasicType::DoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::DoubleImaginary,	BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
+		/* LongDoubleImaginary */ 	{ BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
+		/* SignedInt128 */ 	{ BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::SignedInt128,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::SignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, },
+		/* UnsignedInt128 */ 	{ BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::UnsignedInt128,	BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, },
+		/* Float80 */ 	{ BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::Float80,	BasicType::LongDouble,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::Float80,	BasicType::Float80, BasicType::Float80, BasicType::Float128 },
+		/* Float128 */ 	{ BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::Float128,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::Float128,	BasicType::Float128, BasicType::Float128, BasicType::Float128 },
 	};
+	static_assert(
+		sizeof(combinedType)/sizeof(combinedType[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
+		"Each basic type kind should have a corresponding row in the combined type matrix"
+	);
 
 	CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/ResolvExpr/ConversionCost.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -230,32 +230,40 @@
 */
 
-	static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
-	/* Src \ Dest:	Bool	Char	SChar	UChar	Short	UShort	Int 	UInt	Long	ULong	LLong	ULLong	Float	Double	LDbl	FCplex	DCplex	LDCplex	FImag	DImag	LDImag	I128,	U128 */
-		/* Bool */ 	{ 0,	1,		1,		2,		3,		4,		5,		6,		6,		7,		8,		9,		12,		13,		14,		12,		13,		14,		-1,		-1,		-1,		10,		11,	},
-		/* Char */ 	{ -1,	0,		-1,		1,		2,		3,		4,		5,		5,		6,		7,		8,		11,		12,		13,		11,		12,		13,		-1,		-1,		-1,		9,		10,	},
-		/* SChar */ { -1,	-1,		0,		1,		2,		3,		4,		5,		5,		6,		7,		8,		11,		12,		13,		11,		12,		13,		-1,		-1,		-1,		9,		10,	},
-		/* UChar */ { -1,	-1,		-1,		0,		1,		2,		3,		4,		4,		5,		6,		7,		10,		11,		12,		10,		11,		12,		-1,		-1,		-1,		8,		9,	},
-		/* Short */ { -1,	-1,		-1,		-1,		0,		1,		2,		3,		3,		4,		5,		6,		9,		10,		11,		9,		10,		11,		-1,		-1,		-1,		7,		8,	},
-		/* UShort */{ -1,	-1,		-1,		-1,		-1,		0,		1,		2,		2,		3,		4,		5,		8,		9,		10,		8,		9,		10,		-1,		-1,		-1,		6,		7,	},
-		/* Int */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		0,		1,		1,		2,		3,		4,		7,		8,		9,		7,		8,		9,		-1,		-1,		-1,		5,		6,	},
-		/* UInt */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		1,		2,		3,		6,		7,		8,		6,		7,		8,		-1,		-1,		-1,		4,		5,	},
-		/* Long */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		3,		6,		7,		8,		6,		7,		8,		-1,		-1,		-1,		4,		5,	},
-		/* ULong */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		5,		6,		7,		5,		6,		7,		-1,		-1,		-1,		3,		4,	},
-		/* LLong */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		4,		5,		6,		4,		5,		6,		-1,		-1,		-1,		2,		3,	},
-		/* ULLong */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		3,		4,		5,		3,		4,		5,		-1,		-1,		-1,		1,		2,	},
-
-		/* Float */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		1,		2,		3,		-1,		-1,		-1,		-1,		-1,	},
-		/* Double */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		-1,		1,		2,		-1,		-1,		-1,		-1,		-1,	},
-		/* LDbl */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		1,		-1,		-1,		-1,		-1,		-1,	},
-		/* FCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		-1,		-1,		-1,		-1,		-1,	},
-		/* DCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		-1,		-1,		-1,		-1,		-1,	},
-		/* LDCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		-1,		-1,		-1,	},
-		/* FImag */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		2,		3,		0,		1,		2,		-1,		-1,	},
-		/* DImag */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		2,		-1,		0,		1,		-1,		-1,	},
-		/* LDImag */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		-1,		-1,		0,		-1,		-1,	},
-
-		/* I128 */  { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		2,		3,		4,		3,		4,		5,		-1,		-1,		-1,		0,		1,	},
-		/* U128 */  { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		2,		3,		2,		3,		4,		-1,		-1,		-1,		-1,		0,	},
+	static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
+	/* Src \ Dest:	Bool	Char	SChar	UChar	Short	UShort	Int 	UInt	Long	ULong	LLong	ULLong	Float	Double	LDbl	FCplex	DCplex	LDCplex	FImag	DImag	LDImag	I128,	U128, F80, F128 */
+		/* Bool */ 	{ 0,	1,		1,		2,		3,		4,		5,		6,		6,		7,		8,		9,		12,		13,		14,		12,		13,		14,		-1,		-1,		-1,		10,		11,	  14,   15},
+		/* Char */ 	{ -1,	0,		-1,		1,		2,		3,		4,		5,		5,		6,		7,		8,		11,		12,		13,		11,		12,		13,		-1,		-1,		-1,		9,		10,	  13,   14},
+		/* SChar */ { -1,	-1,		0,		1,		2,		3,		4,		5,		5,		6,		7,		8,		11,		12,		13,		11,		12,		13,		-1,		-1,		-1,		9,		10,	  13,   14},
+		/* UChar */ { -1,	-1,		-1,		0,		1,		2,		3,		4,		4,		5,		6,		7,		10,		11,		12,		10,		11,		12,		-1,		-1,		-1,		8,		9,	  12,   13},
+		/* Short */ { -1,	-1,		-1,		-1,		0,		1,		2,		3,		3,		4,		5,		6,		9,		10,		11,		9,		10,		11,		-1,		-1,		-1,		7,		8,	  11,   12},
+		/* UShort */{ -1,	-1,		-1,		-1,		-1,		0,		1,		2,		2,		3,		4,		5,		8,		9,		10,		8,		9,		10,		-1,		-1,		-1,		6,		7,	  10,   11},
+		/* Int */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		0,		1,		1,		2,		3,		4,		7,		8,		9,		7,		8,		9,		-1,		-1,		-1,		5,		6,	  9,    10},
+		/* UInt */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		1,		2,		3,		6,		7,		8,		6,		7,		8,		-1,		-1,		-1,		4,		5,	  8,    9},
+		/* Long */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		3,		6,		7,		8,		6,		7,		8,		-1,		-1,		-1,		4,		5,	  8,    9},
+		/* ULong */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		5,		6,		7,		5,		6,		7,		-1,		-1,		-1,		3,		4,	  7,    8},
+		/* LLong */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		4,		5,		6,		4,		5,		6,		-1,		-1,		-1,		2,		3,	  6,    7},
+		/* ULLong */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		3,		4,		5,		3,		4,		5,		-1,		-1,		-1,		1,		2,	  5,    6},
+
+		/* Float */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		1,		2,		3,		-1,		-1,		-1,		-1,		-1,	  2,    3},
+		/* Double */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		-1,		1,		2,		-1,		-1,		-1,		-1,		-1,	  1,    2},
+		/* LDbl */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		1,		-1,		-1,		-1,		-1,		-1,	  -1,   1},
+		/* FCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		2,		-1,		-1,		-1,		-1,		-1,	  -1,   -1},
+		/* DCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		1,		-1,		-1,		-1,		-1,		-1,	  -1,   -1},
+		/* LDCplex */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		0,		-1,		-1,		-1,		-1,		-1,	  -1,   -1},
+		/* FImag */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		2,		3,		0,		1,		2,		-1,		-1,	  -1,   -1},
+		/* DImag */ { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		2,		-1,		0,		1,		-1,		-1,	  -1,   -1},
+		/* LDImag */{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		-1,		-1,		0,		-1,		-1,	  -1,   -1},
+
+		/* I128 */  { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		2,		3,		4,		3,		4,		5,		-1,		-1,		-1,		0,		1,	  4,    4},
+		/* U128 */  { -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		2,		3,		2,		3,		4,		-1,		-1,		-1,		-1,		0,	  3,    3},
+
+		/* F80 */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		-1,		-1,		1,		-1,		-1,		-1,		-1,		-1,	  0,    1},
+		/* F128 */ 	{ -1,	-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		-1,		1,		-1,		-1,		-1,		-1,		-1,	  -1,   0},
 	};
+	static_assert(
+		sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
+		"Each basic type kind should have a corresponding row in the cost matrix"
+	);
+
 
 	void ConversionCost::postvisit( VoidType * ) {
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/SymTab/Mangler.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -171,7 +171,14 @@
 					"w",	// SignedInt128
 					"Uw",	// UnsignedInt128
+					"a",   // Float80
+					"A",   // Float128
 				};
+				static_assert(
+					sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
+					"Each basic type kind should have a corresponding mangler letter"
+				);
 
 				printQualifiers( basicType );
+				assert( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]) );
 				mangleName << btLetter[ basicType->get_kind() ];
 			}
Index: src/SynTree/BasicType.cc
===================================================================
--- src/SynTree/BasicType.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/SynTree/BasicType.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -55,4 +55,6 @@
 	  case DoubleImaginary:
 	  case LongDoubleImaginary:
+	  case Float80:
+	  case Float128:
 		return false;
 	  case NUMBER_OF_BASIC_TYPES:
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/SynTree/Type.cc	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -24,5 +24,5 @@
 using namespace std;
 
-const char *BasicType::typeNames[BasicType::NUMBER_OF_BASIC_TYPES] = {
+const char *BasicType::typeNames[] = {
 	"_Bool",
 	"char",
@@ -48,5 +48,11 @@
 	"__int128",
 	"unsigned __int128",
+	"__float80",
+	"__float128"
 };
+static_assert(
+	sizeof(BasicType::typeNames)/sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
+	"Each basic type name should have a corresponding kind enum value"
+);
 
 Type::Type( const Qualifiers &tq, const std::list< Attribute * > & attributes ) : tq( tq ), attributes( attributes ) {}
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/SynTree/Type.h	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -231,4 +231,6 @@
 		SignedInt128,
 		UnsignedInt128,
+		Float80,
+		Float128,
 		NUMBER_OF_BASIC_TYPES
 	} kind;
Index: src/libcfa/bits/locks.h
===================================================================
--- src/libcfa/bits/locks.h	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/libcfa/bits/locks.h	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -39,18 +39,14 @@
 #endif
 
-#if __SIZEOF_SIZE_T__ == 8
-	#define __lock_test_and_test_and_set( lock ) (lock) == 0 && __sync_lock_test_and_set_8( &(lock), 1 ) == 0
-	#define __lock_release( lock ) __sync_lock_release_8( &(lock) );
-#elif __SIZEOF_SIZE_T__ == 4
-	#define __lock_test_and_test_and_set( lock ) (lock) == 0 && __sync_lock_test_and_set_4( &(lock), 1 ) == 0
-	#define __lock_release( lock ) __sync_lock_release_4( &(lock) );
-#else
-	#error unsupported architecture
-#endif
-
 struct __spinlock_t {
-	__ALIGN__ volatile size_t lock;
+	// Wrap in struct to prevent false sharing with debug info
+	struct {
+		// Align lock on 128-bit boundary
+		__ALIGN__ volatile _Bool lock;
+	};
 	#ifdef __CFA_DEBUG__
+		// previous function to acquire the lock
 		const char * prev_name;
+		// previous thread to acquire the lock
 		void* prev_thrd;
 	#endif
@@ -78,5 +74,5 @@
 	// Lock the spinlock, return false if already acquired
 	static inline _Bool try_lock  ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
-		_Bool result = __lock_test_and_test_and_set( this.lock );
+		_Bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);
 		if( result ) {
 			disable_interrupts();
@@ -94,5 +90,5 @@
 
 		for ( unsigned int i = 1;; i += 1 ) {
-			if ( __lock_test_and_test_and_set( this.lock ) ) break;
+			if ( (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0) ) break;
 			#ifndef NOEXPBACK
 				// exponential spin
@@ -112,20 +108,7 @@
 	}
 
-	// // Lock the spinlock, yield if already acquired
-	// static inline void lock_yield( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {
-	// 	for ( unsigned int i = 1;; i += 1 ) {
-	// 		if ( __lock_test_and_test_and_set( this.lock ) ) break;
-	// 		yield( i );
-	// 	}
-	// 	disable_interrupts();
-	// 	__cfaabi_dbg_debug_do(
-	// 		this.prev_name = caller;
-	// 		this.prev_thrd = this_thread;
-	// 	)
-	// }
-
 	static inline void unlock( __spinlock_t & this ) {
 		enable_interrupts_noPoll();
-		__lock_release( this.lock );
+		__atomic_clear( &this.lock, __ATOMIC_RELEASE );
 	}
 #endif
Index: src/libcfa/concurrency/alarm.c
===================================================================
--- src/libcfa/concurrency/alarm.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/libcfa/concurrency/alarm.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -10,6 +10,6 @@
 // Created On       : Fri Jun 2 11:31:25 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Apr  9 13:36:18 2018
-// Update Count     : 61
+// Last Modified On : Fri May 25 06:25:47 2018
+// Update Count     : 67
 //
 
@@ -37,5 +37,5 @@
 
 void __kernel_set_timer( Duration alarm ) {
-	verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%luns)", alarm.tv);
+	verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm.tv);
 	setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL );
 }
Index: src/libcfa/concurrency/preemption.c
===================================================================
--- src/libcfa/concurrency/preemption.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/libcfa/concurrency/preemption.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -161,5 +161,16 @@
 	void disable_interrupts() {
 		with( kernelTLS.preemption_state ) {
-			enabled = false;
+			#if GCC_VERSION > 50000
+			static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
+			#endif
+
+			// Set enabled flag to false
+			// should be atomic to avoid preemption in the middle of the operation.
+			// use memory order RELAXED since there is no inter-thread on this variable requirements
+			__atomic_store_n(&enabled, false, __ATOMIC_RELAXED);
+
+			// Signal the compiler that a fence is needed but only for signal handlers
+			__atomic_signal_fence(__ATOMIC_ACQUIRE);
+
 			__attribute__((unused)) unsigned short new_val = disable_count + 1;
 			disable_count = new_val;
@@ -171,6 +182,6 @@
 	// If counter reaches 0, execute any pending CtxSwitch
 	void enable_interrupts( __cfaabi_dbg_ctx_param ) {
-		processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic add
-		thread_desc * thrd = kernelTLS.this_thread;	  // Cache the thread now since interrupts can start happening after the atomic add
+		processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
+		thread_desc * thrd = kernelTLS.this_thread;	  // Cache the thread now since interrupts can start happening after the atomic store
 
 		with( kernelTLS.preemption_state ){
@@ -181,5 +192,15 @@
 			// Check if we need to prempt the thread because an interrupt was missed
 			if( prev == 1 ) {
-				enabled = true;
+				#if GCC_VERSION > 50000
+				static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
+				#endif
+
+				// Set enabled flag to true
+				// should be atomic to avoid preemption in the middle of the operation.
+				// use memory order RELAXED since there is no inter-thread on this variable requirements
+				__atomic_store_n(&enabled, true, __ATOMIC_RELAXED);
+
+				// Signal the compiler that a fence is needed but only for signal handlers
+				__atomic_signal_fence(__ATOMIC_RELEASE);
 				if( proc->pending_preemption ) {
 					proc->pending_preemption = false;
@@ -200,5 +221,14 @@
 		verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
 		if( prev == 1 ) {
-			kernelTLS.preemption_state.enabled = true;
+			#if GCC_VERSION > 50000
+			static_assert(__atomic_always_lock_free(sizeof(kernelTLS.preemption_state.enabled), &kernelTLS.preemption_state.enabled), "Must be lock-free");
+			#endif
+			// Set enabled flag to true
+			// should be atomic to avoid preemption in the middle of the operation.
+			// use memory order RELAXED since there is no inter-thread on this variable requirements
+			__atomic_store_n(&kernelTLS.preemption_state.enabled, true, __ATOMIC_RELAXED);
+
+			// Signal the compiler that a fence is needed but only for signal handlers
+			__atomic_signal_fence(__ATOMIC_RELEASE);
 		}
 	}
@@ -352,5 +382,7 @@
 
 	// Clear sighandler mask before context switching.
+	#if GCC_VERSION > 50000
 	static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" );
+	#endif
 	if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), NULL ) == -1 ) {
 		abort( "internal error, sigprocmask" );
Index: src/prelude/Makefile.am
===================================================================
--- src/prelude/Makefile.am	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/prelude/Makefile.am	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -37,8 +37,8 @@
 # create forward declarations for gcc builtins
 gcc-builtins.cf : gcc-builtins.c prototypes.sed
-	${AM_V_GEN}@BACKEND_CC@ -E -P $< | sed -f prototypes.sed > $@
+	${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E -P $< | sed -r -f prototypes.sed > $@
 
-gcc-builtins.c : builtins.def prototypes.awk
-	${AM_V_GEN}@BACKEND_CC@ -E prototypes.c | awk -f prototypes.awk > $@
+gcc-builtins.c : builtins.def prototypes.awk sync-builtins.cf
+	${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E prototypes.c | awk -f prototypes.awk > $@
 
 builtins.def :
Index: src/prelude/Makefile.in
===================================================================
--- src/prelude/Makefile.in	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/prelude/Makefile.in	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -506,8 +506,8 @@
 # create forward declarations for gcc builtins
 gcc-builtins.cf : gcc-builtins.c prototypes.sed
-	${AM_V_GEN}@BACKEND_CC@ -E -P $< | sed -f prototypes.sed > $@
-
-gcc-builtins.c : builtins.def prototypes.awk
-	${AM_V_GEN}@BACKEND_CC@ -E prototypes.c | awk -f prototypes.awk > $@
+	${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E -P $< | sed -r -f prototypes.sed > $@
+
+gcc-builtins.c : builtins.def prototypes.awk sync-builtins.cf
+	${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E prototypes.c | awk -f prototypes.awk > $@
 
 builtins.def :
Index: src/prelude/builtins.def
===================================================================
--- src/prelude/builtins.def	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/prelude/builtins.def	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -190,5 +190,5 @@
 
 /* Builtin used by implementation of Cilk Plus.  Most of these are decomposed
-   by the compiler but a few are implemented in libcilkrts.  */ 
+   by the compiler but a few are implemented in libcilkrts.  */
 #undef DEF_CILK_BUILTIN_STUB
 #define DEF_CILK_BUILTIN_STUB(ENUM, NAME) \
@@ -204,5 +204,5 @@
 
 /* Builtin used by the implementation of libsanitizer. These
-   functions are mapped to the actual implementation of the 
+   functions are mapped to the actual implementation of the
    libtsan library. */
 #undef DEF_SANITIZER_BUILTIN
@@ -217,5 +217,5 @@
 #define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS)  \
   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
-  	       false, false, false, ATTRS, false, flag_cilkplus) 
+  	       false, false, false, ATTRS, false, flag_cilkplus)
 
 /* Builtin used by the implementation of Pointer Bounds Checker.  */
@@ -927,8 +927,8 @@
 DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
 
+#if 0 //Ifdefed out because we hard-coded the proper overloadings of the atomic built-ins
 /* Synchronization Primitives.  */
 #include "sync-builtins.def"
 
-#if 0
 /* Offloading and Multi Processing builtins.  */
 #include "omp-builtins.def"
Index: src/prelude/prototypes.awk
===================================================================
--- src/prelude/prototypes.awk	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/prelude/prototypes.awk	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -5,5 +5,5 @@
 # file "LICENCE" distributed with Cforall.
 #
-# prototypes.awk -- 
+# prototypes.awk --
 #
 # Author           : Peter A. Buhr
@@ -12,5 +12,5 @@
 # Last Modified On : Tue Jul  5 14:32:52 2016
 # Update Count     : 32
-# 
+#
 
 # http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def
@@ -83,5 +83,5 @@
 } # BEGIN
 
-/BT_FN/ { 
+/BT_FN/ {
     for (i = 1; i <= NF; i++) {
       if( match($i, "BT_FN") != 0 ) {
@@ -116,5 +116,5 @@
 
       # generate function return type as macro
-      for ( t = 0; t < N; t += 1 ) {					# find longest match 
+      for ( t = 0; t < N; t += 1 ) {					# find longest match
         type = types[t];
         if ( index( prototype, type ) == 1 ) {		# found match
@@ -150,4 +150,5 @@
 	# extras
 	printf( "\n#include \"builtins.def\"\n\n" );
+	printf( "\n#include \"sync-builtins.cf\"\n\n" );
 	printf( "extern const char *__PRETTY_FUNCTION__;\n" );
 } # END
Index: src/prelude/prototypes.sed
===================================================================
--- src/prelude/prototypes.sed	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/prelude/prototypes.sed	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -2,5 +2,21 @@
 /targetm/s/.*//				#Remove targetm declarations
 /__Unsupported/s/.*//			#Remove Unsupported types declarations
-s/void (const char \*)0();//		#Remove void (const char \*)0();
+s/void \(const char \*\)0\(\);//	#Remove void (const char \*)0();
 s/\"//g 					#Remove extraenous quotes in declarations
-/__builtin_/s/_ /_/g			#Remove extraenous spaces in declarations 
+/__builtin_/s/_ /_/g			#Remove extraenous spaces in declarations
+
+#Fix gcc overloading
+# various sed rules for the gcc sync builtins which are overloaded
+# kept here because they generate an acceptable approximate of the correct prototypes
+
+#/__sync_/s/_[0-9][0-9]*\(.*\)/\(\);/g	#hack since it will accept any parameters
+#/__atomic_/s/_[0-9][0-9]*\(.*\)/\(\);/g	#hack since it will accept any parameters
+
+#/_16/s/void \*/__int128 \*/g
+#/_8/s/void \*/long long int \*/g
+#/_4/s/void \*/int \*/g
+#/_2/s/void \*/short \*/g
+#/_1/s/void \*/char \*/g
+
+#s/([a-zA-Z0-9_ ]+)\s+__sync([a-z_]+)_([0-9]+)\((.*)\);/\1 __sync\2\(\4\,...); \1 __sync\2_\3\(\4\,...);/
+#s/([a-zA-Z0-9_ ]+)\s+__atomic([a-z_]+)_([0-9]+)\((.*)\);/\1 __atomic\2\(\4\); \1 __atomic\2_\3\(\4\);/
Index: src/prelude/sync-builtins.cf
===================================================================
--- src/prelude/sync-builtins.cf	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/prelude/sync-builtins.cf	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,468 @@
+char __sync_fetch_and_add(volatile char *, char,...);
+char __sync_fetch_and_add_1(volatile char *, char,...);
+short __sync_fetch_and_add(volatile short *, short,...);
+short __sync_fetch_and_add_2(volatile short *, short,...);
+int __sync_fetch_and_add(volatile int *, int,...);
+int __sync_fetch_and_add_4(volatile int *, int,...);
+long long int __sync_fetch_and_add(volatile long long int *, long long int,...);
+long long int __sync_fetch_and_add_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_fetch_and_add(volatile __int128 *, __int128,...);
+__int128 __sync_fetch_and_add_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_fetch_and_sub(volatile char *, char,...);
+char __sync_fetch_and_sub_1(volatile char *, char,...);
+short __sync_fetch_and_sub(volatile short *, short,...);
+short __sync_fetch_and_sub_2(volatile short *, short,...);
+int __sync_fetch_and_sub(volatile int *, int,...);
+int __sync_fetch_and_sub_4(volatile int *, int,...);
+long long int __sync_fetch_and_sub(volatile long long int *, long long int,...);
+long long int __sync_fetch_and_sub_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_fetch_and_sub(volatile __int128 *, __int128,...);
+__int128 __sync_fetch_and_sub_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_fetch_and_or(volatile char *, char,...);
+char __sync_fetch_and_or_1(volatile char *, char,...);
+short __sync_fetch_and_or(volatile short *, short,...);
+short __sync_fetch_and_or_2(volatile short *, short,...);
+int __sync_fetch_and_or(volatile int *, int,...);
+int __sync_fetch_and_or_4(volatile int *, int,...);
+long long int __sync_fetch_and_or(volatile long long int *, long long int,...);
+long long int __sync_fetch_and_or_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_fetch_and_or(volatile __int128 *, __int128,...);
+__int128 __sync_fetch_and_or_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_fetch_and_and(volatile char *, char,...);
+char __sync_fetch_and_and_1(volatile char *, char,...);
+short __sync_fetch_and_and(volatile short *, short,...);
+short __sync_fetch_and_and_2(volatile short *, short,...);
+int __sync_fetch_and_and(volatile int *, int,...);
+int __sync_fetch_and_and_4(volatile int *, int,...);
+long long int __sync_fetch_and_and(volatile long long int *, long long int,...);
+long long int __sync_fetch_and_and_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_fetch_and_and(volatile __int128 *, __int128,...);
+__int128 __sync_fetch_and_and_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_fetch_and_xor(volatile char *, char,...);
+char __sync_fetch_and_xor_1(volatile char *, char,...);
+short __sync_fetch_and_xor(volatile short *, short,...);
+short __sync_fetch_and_xor_2(volatile short *, short,...);
+int __sync_fetch_and_xor(volatile int *, int,...);
+int __sync_fetch_and_xor_4(volatile int *, int,...);
+long long int __sync_fetch_and_xor(volatile long long int *, long long int,...);
+long long int __sync_fetch_and_xor_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_fetch_and_xor(volatile __int128 *, __int128,...);
+__int128 __sync_fetch_and_xor_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_fetch_and_nand(volatile char *, char,...);
+char __sync_fetch_and_nand_1(volatile char *, char,...);
+short __sync_fetch_and_nand(volatile short *, short,...);
+short __sync_fetch_and_nand_2(volatile short *, short,...);
+int __sync_fetch_and_nand(volatile int *, int,...);
+int __sync_fetch_and_nand_4(volatile int *, int,...);
+long long int __sync_fetch_and_nand(volatile long long int *, long long int,...);
+long long int __sync_fetch_and_nand_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_fetch_and_nand(volatile __int128 *, __int128,...);
+__int128 __sync_fetch_and_nand_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_add_and_fetch(volatile char *, char,...);
+char __sync_add_and_fetch_1(volatile char *, char,...);
+short __sync_add_and_fetch(volatile short *, short,...);
+short __sync_add_and_fetch_2(volatile short *, short,...);
+int __sync_add_and_fetch(volatile int *, int,...);
+int __sync_add_and_fetch_4(volatile int *, int,...);
+long long int __sync_add_and_fetch(volatile long long int *, long long int,...);
+long long int __sync_add_and_fetch_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_add_and_fetch(volatile __int128 *, __int128,...);
+__int128 __sync_add_and_fetch_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_sub_and_fetch(volatile char *, char,...);
+char __sync_sub_and_fetch_1(volatile char *, char,...);
+short __sync_sub_and_fetch(volatile short *, short,...);
+short __sync_sub_and_fetch_2(volatile short *, short,...);
+int __sync_sub_and_fetch(volatile int *, int,...);
+int __sync_sub_and_fetch_4(volatile int *, int,...);
+long long int __sync_sub_and_fetch(volatile long long int *, long long int,...);
+long long int __sync_sub_and_fetch_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_sub_and_fetch(volatile __int128 *, __int128,...);
+__int128 __sync_sub_and_fetch_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_or_and_fetch(volatile char *, char,...);
+char __sync_or_and_fetch_1(volatile char *, char,...);
+short __sync_or_and_fetch(volatile short *, short,...);
+short __sync_or_and_fetch_2(volatile short *, short,...);
+int __sync_or_and_fetch(volatile int *, int,...);
+int __sync_or_and_fetch_4(volatile int *, int,...);
+long long int __sync_or_and_fetch(volatile long long int *, long long int,...);
+long long int __sync_or_and_fetch_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_or_and_fetch(volatile __int128 *, __int128,...);
+__int128 __sync_or_and_fetch_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_and_and_fetch(volatile char *, char,...);
+char __sync_and_and_fetch_1(volatile char *, char,...);
+short __sync_and_and_fetch(volatile short *, short,...);
+short __sync_and_and_fetch_2(volatile short *, short,...);
+int __sync_and_and_fetch(volatile int *, int,...);
+int __sync_and_and_fetch_4(volatile int *, int,...);
+long long int __sync_and_and_fetch(volatile long long int *, long long int,...);
+long long int __sync_and_and_fetch_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_and_and_fetch(volatile __int128 *, __int128,...);
+__int128 __sync_and_and_fetch_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_xor_and_fetch(volatile char *, char,...);
+char __sync_xor_and_fetch_1(volatile char *, char,...);
+short __sync_xor_and_fetch(volatile short *, short,...);
+short __sync_xor_and_fetch_2(volatile short *, short,...);
+int __sync_xor_and_fetch(volatile int *, int,...);
+int __sync_xor_and_fetch_4(volatile int *, int,...);
+long long int __sync_xor_and_fetch(volatile long long int *, long long int,...);
+long long int __sync_xor_and_fetch_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_xor_and_fetch(volatile __int128 *, __int128,...);
+__int128 __sync_xor_and_fetch_16(volatile __int128 *, __int128,...);
+#endif
+
+char __sync_nand_and_fetch(volatile char *, char,...);
+char __sync_nand_and_fetch_1(volatile char *, char,...);
+short __sync_nand_and_fetch(volatile short *, short,...);
+short __sync_nand_and_fetch_2(volatile short *, short,...);
+int __sync_nand_and_fetch(volatile int *, int,...);
+int __sync_nand_and_fetch_4(volatile int *, int,...);
+long long int __sync_nand_and_fetch(volatile long long int *, long long int,...);
+long long int __sync_nand_and_fetch_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_nand_and_fetch(volatile __int128 *, __int128,...);
+__int128 __sync_nand_and_fetch_16(volatile __int128 *, __int128,...);
+#endif
+
+_Bool __sync_bool_compare_and_swap(volatile char *, char, char,...);
+_Bool __sync_bool_compare_and_swap_1(volatile char *, char, char,...);
+_Bool __sync_bool_compare_and_swap(volatile short *, short, short,...);
+_Bool __sync_bool_compare_and_swap_2(volatile short *, short, short,...);
+_Bool __sync_bool_compare_and_swap(volatile int *, int, int,...);
+_Bool __sync_bool_compare_and_swap_4(volatile int *, int, int,...);
+_Bool __sync_bool_compare_and_swap(volatile long long int *, long long int, long long int,...);
+_Bool __sync_bool_compare_and_swap_8(volatile long long int *, long long int, long long int,...);
+#if defined(__SIZEOF_INT128__)
+_Bool __sync_bool_compare_and_swap(volatile __int128 *, __int128, __int128,...);
+_Bool __sync_bool_compare_and_swap_16(volatile __int128 *, __int128, __int128,...);
+#endif
+
+char __sync_val_compare_and_swap(volatile char *, char, char,...);
+char __sync_val_compare_and_swap_1(volatile char *, char, char,...);
+short __sync_val_compare_and_swap(volatile short *, short, short,...);
+short __sync_val_compare_and_swap_2(volatile short *, short, short,...);
+int __sync_val_compare_and_swap(volatile int *, int, int,...);
+int __sync_val_compare_and_swap_4(volatile int *, int, int,...);
+long long int __sync_val_compare_and_swap(volatile long long int *, long long int, long long int,...);
+long long int __sync_val_compare_and_swap_8(volatile long long int *, long long int, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_val_compare_and_swap(volatile __int128 *, __int128, __int128,...);
+__int128 __sync_val_compare_and_swap_16(volatile __int128 *, __int128, __int128,...);
+#endif
+
+char __sync_lock_test_and_set(volatile char *, char,...);
+char __sync_lock_test_and_set_1(volatile char *, char,...);
+short __sync_lock_test_and_set(volatile short *, short,...);
+short __sync_lock_test_and_set_2(volatile short *, short,...);
+int __sync_lock_test_and_set(volatile int *, int,...);
+int __sync_lock_test_and_set_4(volatile int *, int,...);
+long long int __sync_lock_test_and_set(volatile long long int *, long long int,...);
+long long int __sync_lock_test_and_set_8(volatile long long int *, long long int,...);
+#if defined(__SIZEOF_INT128__)
+__int128 __sync_lock_test_and_set(volatile __int128 *, __int128,...);
+__int128 __sync_lock_test_and_set_16(volatile __int128 *, __int128,...);
+#endif
+
+void __sync_lock_release(volatile char *,...);
+void __sync_lock_release_1(volatile char *,...);
+void __sync_lock_release(volatile short *,...);
+void __sync_lock_release_2(volatile short *,...);
+void __sync_lock_release(volatile int *,...);
+void __sync_lock_release_4(volatile int *,...);
+void __sync_lock_release(volatile long long int *,...);
+void __sync_lock_release_8(volatile long long int *,...);
+#if defined(__SIZEOF_INT128__)
+void __sync_lock_release(volatile __int128 *,...);
+void __sync_lock_release_16(volatile __int128 *,...);
+#endif
+
+void __sync_synchronize();
+
+
+
+
+_Bool __atomic_test_and_set(volatile _Bool *, int);
+_Bool __atomic_test_and_set(volatile char *, int);
+_Bool __atomic_test_and_set(volatile short *, int);
+_Bool __atomic_test_and_set(volatile int *, int);
+_Bool __atomic_test_and_set(volatile long long int *, int);
+#if defined(__SIZEOF_INT128__)
+_Bool __atomic_test_and_set(volatile __int128 *, int);
+#endif
+
+void __atomic_clear(volatile _Bool *, int);
+void __atomic_clear(volatile char *, int);
+void __atomic_clear(volatile short *, int);
+void __atomic_clear(volatile int *, int);
+void __atomic_clear(volatile long long int *, int);
+#if defined(__SIZEOF_INT128__)
+void __atomic_clear(volatile __int128 *, int);
+#endif
+
+char __atomic_exchange_n(volatile char *, volatile char *, int);
+char __atomic_exchange_1(volatile char *, char, int);
+void __atomic_exchange(volatile char *, volatile char *, volatile char *, int);
+short __atomic_exchange_n(volatile short *, volatile short *, int);
+short __atomic_exchange_2(volatile short *, short, int);
+void __atomic_exchange(volatile short *, volatile short *, volatile short *, int);
+int __atomic_exchange_n(volatile int *, volatile int *, int);
+int __atomic_exchange_4(volatile int *, int, int);
+void __atomic_exchange(volatile int *, volatile int *, volatile int *, int);
+long long int __atomic_exchange_n(volatile long long int *, volatile long long int *, int);
+long long int __atomic_exchange_8(volatile long long int *, long long int, int);
+void __atomic_exchange(volatile long long int *, volatile long long int *, volatile long long int *, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_exchange_n(volatile __int128 *, volatile __int128 *, int);
+__int128 __atomic_exchange_16(volatile __int128 *, __int128, int);
+void __atomic_exchange(volatile __int128 *, volatile __int128 *, volatile __int128 *, int);
+#endif
+
+char __atomic_load_n(const volatile char *, int);
+char __atomic_load_1(const volatile char *, int);
+void __atomic_load(const volatile char *, volatile char *, int);
+short __atomic_load_n(const volatile short *, int);
+short __atomic_load_2(const volatile short *, int);
+void __atomic_load(const volatile short *, volatile short *, int);
+int __atomic_load_n(const volatile int *, int);
+int __atomic_load_4(const volatile int *, int);
+void __atomic_load(const volatile int *, volatile int *, int);
+long long int __atomic_load_n(const volatile long long int *, int);
+long long int __atomic_load_8(const volatile long long int *, int);
+void __atomic_load(const volatile long long int *, volatile long long int *, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_load_n(const volatile __int128 *, int);
+__int128 __atomic_load_16(const volatile __int128 *, int);
+void __atomic_load(const volatile __int128 *, volatile __int128 *, int);
+#endif
+
+_Bool __atomic_compare_exchange_n(volatile char *, char *, char, _Bool, int, int);
+_Bool __atomic_compare_exchange_1(volatile char *, char *, char, _Bool, int, int);
+_Bool __atomic_compare_exchange  (volatile char *, char *, char *, _Bool, int, int);
+_Bool __atomic_compare_exchange_n(volatile short *, short *, short, _Bool, int, int);
+_Bool __atomic_compare_exchange_2(volatile short *, short *, short, _Bool, int, int);
+_Bool __atomic_compare_exchange  (volatile short *, short *, short *, _Bool, int, int);
+_Bool __atomic_compare_exchange_n(volatile int *, int *, int, _Bool, int, int);
+_Bool __atomic_compare_exchange_4(volatile int *, int *, int, _Bool, int, int);
+_Bool __atomic_compare_exchange  (volatile int *, int *, int *, _Bool, int, int);
+_Bool __atomic_compare_exchange_n(volatile long long int *, long long int *, long long int, _Bool, int, int);
+_Bool __atomic_compare_exchange_8(volatile long long int *, long long int *, long long int, _Bool, int, int);
+_Bool __atomic_compare_exchange  (volatile long long int *, long long int *, long long int *, _Bool, int, int);
+#if defined(__SIZEOF_INT128__)
+_Bool __atomic_compare_exchange_n (volatile __int128 *, __int128 *, __int128, _Bool, int, int);
+_Bool __atomic_compare_exchange_16(volatile __int128 *, __int128 *, __int128, _Bool, int, int);
+_Bool __atomic_compare_exchange   (volatile __int128 *, __int128 *, __int128 *, _Bool, int, int);
+#endif
+
+void __atomic_store_n(volatile _Bool *, _Bool, int);
+void __atomic_store_1(volatile _Bool *, _Bool, int);
+void __atomic_store(volatile _Bool *, _Bool *, int);
+void __atomic_store_n(volatile char *, char, int);
+void __atomic_store_1(volatile char *, char, int);
+void __atomic_store(volatile char *, char *, int);
+void __atomic_store_n(volatile short *, short, int);
+void __atomic_store_2(volatile short *, short, int);
+void __atomic_store(volatile short *, short *, int);
+void __atomic_store_n(volatile int *, int, int);
+void __atomic_store_4(volatile int *, int, int);
+void __atomic_store(volatile int *, int *, int);
+void __atomic_store_n(volatile long long int *, long long int, int);
+void __atomic_store_8(volatile long long int *, long long int, int);
+void __atomic_store(volatile long long int *, long long int *, int);
+#if defined(__SIZEOF_INT128__)
+void __atomic_store_n(volatile __int128 *, __int128, int);
+void __atomic_store_16(volatile __int128 *, __int128, int);
+void __atomic_store(volatile __int128 *, __int128 *, int);
+#endif
+
+char __atomic_add_fetch  (volatile char *, char, int);
+char __atomic_add_fetch_1(volatile char *, char, int);
+short __atomic_add_fetch  (volatile short *, short, int);
+short __atomic_add_fetch_2(volatile short *, short, int);
+int __atomic_add_fetch  (volatile int *, int, int);
+int __atomic_add_fetch_4(volatile int *, int, int);
+long long int __atomic_add_fetch  (volatile long long int *, long long int, int);
+long long int __atomic_add_fetch_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_add_fetch   (volatile __int128 *, __int128, int);
+__int128 __atomic_add_fetch_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_sub_fetch  (volatile char *, char, int);
+char __atomic_sub_fetch_1(volatile char *, char, int);
+short __atomic_sub_fetch  (volatile short *, short, int);
+short __atomic_sub_fetch_2(volatile short *, short, int);
+int __atomic_sub_fetch  (volatile int *, int, int);
+int __atomic_sub_fetch_4(volatile int *, int, int);
+long long int __atomic_sub_fetch  (volatile long long int *, long long int, int);
+long long int __atomic_sub_fetch_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_sub_fetch   (volatile __int128 *, __int128, int);
+__int128 __atomic_sub_fetch_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_and_fetch  (volatile char *, char, int);
+char __atomic_and_fetch_1(volatile char *, char, int);
+short __atomic_and_fetch  (volatile short *, short, int);
+short __atomic_and_fetch_2(volatile short *, short, int);
+int __atomic_and_fetch  (volatile int *, int, int);
+int __atomic_and_fetch_4(volatile int *, int, int);
+long long int __atomic_and_fetch  (volatile long long int *, long long int, int);
+long long int __atomic_and_fetch_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_and_fetch   (volatile __int128 *, __int128, int);
+__int128 __atomic_and_fetch_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_nand_fetch  (volatile char *, char, int);
+char __atomic_nand_fetch_1(volatile char *, char, int);
+short __atomic_nand_fetch  (volatile short *, short, int);
+short __atomic_nand_fetch_2(volatile short *, short, int);
+int __atomic_nand_fetch  (volatile int *, int, int);
+int __atomic_nand_fetch_4(volatile int *, int, int);
+long long int __atomic_nand_fetch  (volatile long long int *, long long int, int);
+long long int __atomic_nand_fetch_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_nand_fetch   (volatile __int128 *, __int128, int);
+__int128 __atomic_nand_fetch_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_xor_fetch  (volatile char *, char, int);
+char __atomic_xor_fetch_1(volatile char *, char, int);
+short __atomic_xor_fetch  (volatile short *, short, int);
+short __atomic_xor_fetch_2(volatile short *, short, int);
+int __atomic_xor_fetch  (volatile int *, int, int);
+int __atomic_xor_fetch_4(volatile int *, int, int);
+long long int __atomic_xor_fetch  (volatile long long int *, long long int, int);
+long long int __atomic_xor_fetch_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_xor_fetch   (volatile __int128 *, __int128, int);
+__int128 __atomic_xor_fetch_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_or_fetch  (volatile char *, char, int);
+char __atomic_or_fetch_1(volatile char *, char, int);
+short __atomic_or_fetch  (volatile short *, short, int);
+short __atomic_or_fetch_2(volatile short *, short, int);
+int __atomic_or_fetch  (volatile int *, int, int);
+int __atomic_or_fetch_4(volatile int *, int, int);
+long long int __atomic_or_fetch  (volatile long long int *, long long int, int);
+long long int __atomic_or_fetch_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_or_fetch   (volatile __int128 *, __int128, int);
+__int128 __atomic_or_fetch_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_fetch_add  (volatile char *, char, int);
+char __atomic_fetch_add_1(volatile char *, char, int);
+short __atomic_fetch_add  (volatile short *, short, int);
+short __atomic_fetch_add_2(volatile short *, short, int);
+int __atomic_fetch_add  (volatile int *, int, int);
+int __atomic_fetch_add_4(volatile int *, int, int);
+long long int __atomic_fetch_add  (volatile long long int *, long long int, int);
+long long int __atomic_fetch_add_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_fetch_add   (volatile __int128 *, __int128, int);
+__int128 __atomic_fetch_add_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_fetch_sub  (volatile char *, char, int);
+char __atomic_fetch_sub_1(volatile char *, char, int);
+short __atomic_fetch_sub  (volatile short *, short, int);
+short __atomic_fetch_sub_2(volatile short *, short, int);
+int __atomic_fetch_sub  (volatile int *, int, int);
+int __atomic_fetch_sub_4(volatile int *, int, int);
+long long int __atomic_fetch_sub  (volatile long long int *, long long int, int);
+long long int __atomic_fetch_sub_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_fetch_sub   (volatile __int128 *, __int128, int);
+__int128 __atomic_fetch_sub_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_fetch_and  (volatile char *, char, int);
+char __atomic_fetch_and_1(volatile char *, char, int);
+short __atomic_fetch_and  (volatile short *, short, int);
+short __atomic_fetch_and_2(volatile short *, short, int);
+int __atomic_fetch_and  (volatile int *, int, int);
+int __atomic_fetch_and_4(volatile int *, int, int);
+long long int __atomic_fetch_and  (volatile long long int *, long long int, int);
+long long int __atomic_fetch_and_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_fetch_and   (volatile __int128 *, __int128, int);
+__int128 __atomic_fetch_and_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_fetch_nand  (volatile char *, char, int);
+char __atomic_fetch_nand_1(volatile char *, char, int);
+short __atomic_fetch_nand  (volatile short *, short, int);
+short __atomic_fetch_nand_2(volatile short *, short, int);
+int __atomic_fetch_nand  (volatile int *, int, int);
+int __atomic_fetch_nand_4(volatile int *, int, int);
+long long int __atomic_fetch_nand  (volatile long long int *, long long int, int);
+long long int __atomic_fetch_nand_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_fetch_nand   (volatile __int128 *, __int128, int);
+__int128 __atomic_fetch_nand_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_fetch_xor  (volatile char *, char, int);
+char __atomic_fetch_xor_1(volatile char *, char, int);
+short __atomic_fetch_xor  (volatile short *, short, int);
+short __atomic_fetch_xor_2(volatile short *, short, int);
+int __atomic_fetch_xor  (volatile int *, int, int);
+int __atomic_fetch_xor_4(volatile int *, int, int);
+long long int __atomic_fetch_xor  (volatile long long int *, long long int, int);
+long long int __atomic_fetch_xor_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_fetch_xor   (volatile __int128 *, __int128, int);
+__int128 __atomic_fetch_xor_16(volatile __int128 *, __int128, int);
+#endif
+
+char __atomic_fetch_or  (volatile char *, char, int);
+char __atomic_fetch_or_1(volatile char *, char, int);
+short __atomic_fetch_or  (volatile short *, short, int);
+short __atomic_fetch_or_2(volatile short *, short, int);
+int __atomic_fetch_or  (volatile int *, int, int);
+int __atomic_fetch_or_4(volatile int *, int, int);
+long long int __atomic_fetch_or  (volatile long long int *, long long int, int);
+long long int __atomic_fetch_or_8(volatile long long int *, long long int, int);
+#if defined(__SIZEOF_INT128__)
+__int128 __atomic_fetch_or   (volatile __int128 *, __int128, int);
+__int128 __atomic_fetch_or_16(volatile __int128 *, __int128, int);
+#endif
+
+_Bool __atomic_always_lock_free(unsigned long, const volatile void *);
+_Bool __atomic_is_lock_free(unsigned long, const volatile void *);
+
+void __atomic_thread_fence (int);
+void __atomic_signal_fence (int);
+void __atomic_feraiseexcept(int);
Index: c/tests/.expect/io.txt
===================================================================
--- src/tests/.expect/io.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ 	(revision )
@@ -1,85 +1,0 @@
-9 6 28 0 7 1 2
-1 2 3
-123
-123
-
-opening delimiters
-x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
-
-closing delimiters
-1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
-
-opening/closing delimiters
-x`1`x'2'x"3"x:4:x 5 x	6	x
-7
-x
-8
-x
-9
-x
-10
-x
-
-override opening/closing delimiters
-x ( 1 ) x 2 , x 3 :x: 4
-
-input bacis types
-
-output basic types
-false
-A 23 93
-1 2 3 4 5 6 7 8
-1.1 1.2 1.3
-1.1+2.3i 1.1-2.3i 1.1-2.3i
-
-tuples
-1, 2, 3 4, 5, 6
-
-toggle separator
-1.11.21.3
-1.1+2.3i1.1-2.3i1.1-2.3i
-1.1+2.3i 1.1-2.3i1.1-2.3i
-1.1+2.3i 1.1-2.3i 1.1-2.3i
-1.1+2.3i1.1-2.3i 1.1-2.3i
-abcxyz
-abcxyz
-
-change separator
-from " " to ", $"
-1.1, $1.2, $1.3
-1.1+2.3i, $1.1-2.3i, $1.1-2.3i
-abc, $xyz
-1, 2, 3, $4, 5, 6
-
-from ", $" to " "
-1.1 1.2 1.3
-1.1+2.3i 1.1-2.3i 1.1-2.3i
-abc xyz
-1, 2, 3 4, 5, 6
-
-check sepOn/sepOff
-1 2 3
-12 3
-1 2 3
-1 2 3
-
-1 2 3
-
-check enable/disable
-123
-1 23
-1 2 3
-123
-1 2 3
-123
-1 2 3
-
-1 2 3 4 5 6 " "
-1, 2, 3 4, 5, 6 " "
-1, 2, 3 4, 5, 6
-
-3, 4, a, 7.2
-3, 4, a, 7.2
-3 4 a 7.2
-3 4 a 7.234a7.23 4 a 7.2
-3-4-a-7.2^3^4^3-4-a-7.2
Index: src/tests/.expect/io1.txt
===================================================================
--- src/tests/.expect/io1.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/.expect/io1.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,25 @@
+9 6 28 0 7 1 2
+1 2 3
+123
+123
+
+opening delimiters
+x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
+
+closing delimiters
+1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
+
+opening/closing delimiters
+x`1`x'2'x"3"x:4:x 5 x	6	x
+7
+x
+8
+x
+9
+x
+10
+x
+
+override opening/closing delimiters
+x ( 1 ) x 2 , x 3 :x: 4
+
Index: src/tests/.expect/io2.txt
===================================================================
--- src/tests/.expect/io2.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/.expect/io2.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,60 @@
+input bacis types
+
+output basic types
+false
+A 23 93
+1 2 3 4 5 6 7 8
+1.1 1.2 1.3
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+
+tuples
+1, 2, 3 4, 5, 6
+
+toggle separator
+1.11.21.3
+1.1+2.3i1.1-2.3i1.1-2.3i
+1.1+2.3i 1.1-2.3i1.1-2.3i
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+1.1+2.3i1.1-2.3i 1.1-2.3i
+abcxyz
+abcxyz
+
+change separator
+from " " to ", $"
+1.1, $1.2, $1.3
+1.1+2.3i, $1.1-2.3i, $1.1-2.3i
+abc, $xyz
+1, 2, 3, $4, 5, 6
+
+from ", $" to " "
+1.1 1.2 1.3
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+abc xyz
+1, 2, 3 4, 5, 6
+
+check sepOn/sepOff
+1 2 3
+12 3
+1 2 3
+1 2 3
+
+1 2 3
+
+check enable/disable
+123
+1 23
+1 2 3
+123
+1 2 3
+123
+1 2 3
+
+1 2 3 4 5 6 " "
+1, 2, 3 4, 5, 6 " "
+1, 2, 3 4, 5, 6
+
+3, 4, a, 7.2
+3, 4, a, 7.2
+3 4 a 7.2
+3 4 a 7.234a7.23 4 a 7.2
+3-4-a-7.2^3^4^3-4-a-7.2
Index: src/tests/.expect/math1.x64.txt
===================================================================
--- src/tests/.expect/math1.x64.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/.expect/math1.x64.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -12,11 +12,2 @@
 \ 16 256
 \ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
-log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
-log2:3 3 3
-log10:2 2 2
-log1p:0.693147 0.693147180559945 0.693147180559945309
-ilogb:0 0 0
-logb:3 3 3
-sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
-cbrt:3 3 3
-hypot:1.41421 1.4142135623731 1.41421356237309505
Index: src/tests/.expect/math1.x86.txt
===================================================================
--- src/tests/.expect/math1.x86.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/.expect/math1.x86.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -12,11 +12,2 @@
 \ 16 256
 \ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
-log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
-log2:3 3 3
-log10:2 2 2
-log1p:0.693147 0.693147180559945 0.693147180559945309
-ilogb:0 0 0
-logb:3 3 3
-sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
-cbrt:3 3 3
-hypot:1.41421 1.4142135623731 1.41421356237309505
Index: src/tests/.expect/math2.x64.txt
===================================================================
--- src/tests/.expect/math2.x64.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/.expect/math2.x64.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,2 +1,11 @@
+log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
+log2:3 3 3
+log10:2 2 2
+log1p:0.693147 0.693147180559945 0.693147180559945309
+ilogb:0 0 0
+logb:3 3 3
+sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
+cbrt:3 3 3
+hypot:1.41421 1.4142135623731 1.41421356237309505
 sin:0.841471 0.841470984807897 0.841470984807896507 1.29846+0.634964i 1.29845758141598+0.634963914784736i 1.29845758141597729+0.634963914784736108i
 cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
@@ -6,13 +15,2 @@
 atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
 atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831
-sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
-cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
-tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
-acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
-asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
-atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
-erf:0.842701 0.842700792949715 0.842700792949714869
-erfc:0.157299 0.157299207050285 0.157299207050285131
-lgamma:1.79176 1.79175946922805 1.791759469228055
-lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
-tgamma:6 6 6
Index: src/tests/.expect/math2.x86.txt
===================================================================
--- src/tests/.expect/math2.x86.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/.expect/math2.x86.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,2 +1,11 @@
+log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
+log2:3 3 3
+log10:2 2 2
+log1p:0.693147 0.693147180559945 0.693147180559945309
+ilogb:0 0 0
+logb:3 3 3
+sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
+cbrt:3 3 3
+hypot:1.41421 1.4142135623731 1.41421356237309505
 sin:0.841471 0.841470984807897 0.841470984807896507 1.29846+0.634964i 1.29845758141598+0.634963914784736i 1.29845758141597729+0.634963914784736108i
 cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
@@ -6,13 +15,2 @@
 atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
 atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831
-sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
-cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
-tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
-acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
-asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
-atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
-erf:0.842701 0.842700792949715 0.842700792949714869
-erfc:0.157299 0.157299207050285 0.157299207050285131
-lgamma:1.79176 1.79175946922805 1.791759469228055
-lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
-tgamma:6 6 6
Index: src/tests/.expect/math3.x64.txt
===================================================================
--- src/tests/.expect/math3.x64.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/.expect/math3.x64.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,23 +1,11 @@
-floor:1 1 1
-ceil:2 2 2
-trunc:3 3 3
-rint:2 2 2
-rint:2 2 2
-rint:2 2 2
-lrint:2 2 2
-llrint:2 2 2
-nearbyint:4 4 4
-round:2 2 2
-round:2 2 2
-round:2 2 2
-lround:2 2 2
-llround:2 2 2
-copysign:-1 -1 -1
-frexp:0.5 3 0.5 3 0.5 3
-ldexp:8 8 8
-modf:2 0.3 2 0.3 2 0.3
-modf:2, 0.3 2, 0.3 2, 0.3
-nextafter:2 2 2
-nexttoward:2 2 2
-scalbn:16 16 16
-scalbln:16 16 16
+sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
+cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
+tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
+acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
+asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
+atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
+erf:0.842701 0.842700792949715 0.842700792949714869
+erfc:0.157299 0.157299207050285 0.157299207050285131
+lgamma:1.79176 1.79175946922805 1.791759469228055
+lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
+tgamma:6 6 6
Index: src/tests/.expect/math3.x86.txt
===================================================================
--- src/tests/.expect/math3.x86.txt	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/.expect/math3.x86.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,23 +1,11 @@
-floor:1 1 1
-ceil:2 2 2
-trunc:3 3 3
-rint:2 2 2
-rint:2 2 2
-rint:2 2 2
-lrint:2 2 2
-llrint:2 2 2
-nearbyint:4 4 4
-round:2 2 2
-round:2 2 2
-round:2 2 2
-lround:2 2 2
-llround:2 2 2
-copysign:-1 -1 -1
-frexp:0.5 3 0.5 3 0.5 3
-ldexp:8 8 8
-modf:2 0.3 2 0.3 2 0.3
-modf:2, 0.3 2, 0.3 2, 0.3
-nextafter:2 2 2
-nexttoward:2 2 2
-scalbn:16 16 16
-scalbln:16 16 16
+sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
+cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
+tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
+acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
+asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
+atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
+erf:0.842701 0.842700792949715 0.842700792949714869
+erfc:0.157299 0.157299207050285 0.157299207050285131
+lgamma:1.79176 1.79175946922805 1.791759469228055
+lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
+tgamma:6 6 6
Index: src/tests/.expect/math4.x64.txt
===================================================================
--- src/tests/.expect/math4.x64.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/.expect/math4.x64.txt	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,23 @@
+floor:1 1 1
+ceil:2 2 2
+trunc:3 3 3
+rint:2 2 2
+rint:2 2 2
+rint:2 2 2
+lrint:2 2 2
+llrint:2 2 2
+nearbyint:4 4 4
+round:2 2 2
+round:2 2 2
+round:2 2 2
+lround:2 2 2
+llround:2 2 2
+copysign:-1 -1 -1
+frexp:0.5 3 0.5 3 0.5 3
+ldexp:8 8 8
+modf:2 0.3 2 0.3 2 0.3
+modf:2, 0.3 2, 0.3 2, 0.3
+nextafter:2 2 2
+nexttoward:2 2 2
+scalbn:16 16 16
+scalbln:16 16 16
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/Makefile.am	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -129,2 +129,6 @@
 warnings/self-assignment: warnings/self-assignment.c @CFA_BINDIR@/@CFA_NAME@
 	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
+
+#builtins
+builtins/sync: builtins/sync.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/Makefile.in	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -807,4 +807,8 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
 
+#builtins
+builtins/sync: builtins/sync.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
Index: src/tests/builtins/sync.c
===================================================================
--- src/tests/builtins/sync.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/builtins/sync.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,468 @@
+#include <stdbool.h>
+#include <stdint.h>
+
+void foo() {
+	volatile _Bool * vpB = 0; _Bool vB = 0;
+	volatile char * vp1 = 0; char * rp1 = 0; char v1 = 0;
+	volatile short * vp2 = 0; short * rp2 = 0; short v2 = 0;
+	volatile int * vp4 = 0; int * rp4 = 0; int v4 = 0;
+	volatile long long int * vp8 = 0; long long int * rp8 = 0; long long int v8 = 0;
+	#if defined(__SIZEOF_INT128__)
+	volatile __int128 * vp16 = 0; __int128 * rp16 = 0; __int128 v16 = 0;
+	#endif
+
+	{ char ret; ret = __sync_fetch_and_add(vp1, v1); }
+	{ char ret; ret = __sync_fetch_and_add_1(vp1, v1); }
+	{ short ret; ret = __sync_fetch_and_add(vp2, v2); }
+	{ short ret; ret = __sync_fetch_and_add_2(vp2, v2); }
+	{ int ret; ret = __sync_fetch_and_add(vp4, v4); }
+	{ int ret; ret = __sync_fetch_and_add_4(vp4, v4); }
+	{ long long int ret; ret = __sync_fetch_and_add(vp8, v8); }
+	{ long long int ret; ret = __sync_fetch_and_add_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_fetch_and_add(vp16, v16); }
+	{ __int128 ret; ret = __sync_fetch_and_add_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_fetch_and_sub(vp1, v1); }
+	{ char ret; ret = __sync_fetch_and_sub_1(vp1, v1); }
+	{ short ret; ret = __sync_fetch_and_sub(vp2, v2); }
+	{ short ret; ret = __sync_fetch_and_sub_2(vp2, v2); }
+	{ int ret; ret = __sync_fetch_and_sub(vp4, v4); }
+	{ int ret; ret = __sync_fetch_and_sub_4(vp4, v4); }
+	{ long long int ret; ret = __sync_fetch_and_sub(vp8, v8); }
+	{ long long int ret; ret = __sync_fetch_and_sub_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_fetch_and_sub(vp16, v16); }
+	{ __int128 ret; ret = __sync_fetch_and_sub_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_fetch_and_or(vp1, v1); }
+	{ char ret; ret = __sync_fetch_and_or_1(vp1, v1); }
+	{ short ret; ret = __sync_fetch_and_or(vp2, v2); }
+	{ short ret; ret = __sync_fetch_and_or_2(vp2, v2); }
+	{ int ret; ret = __sync_fetch_and_or(vp4, v4); }
+	{ int ret; ret = __sync_fetch_and_or_4(vp4, v4); }
+	{ long long int ret; ret = __sync_fetch_and_or(vp8, v8); }
+	{ long long int ret; ret = __sync_fetch_and_or_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_fetch_and_or(vp16, v16); }
+	{ __int128 ret; ret = __sync_fetch_and_or_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_fetch_and_and(vp1, v1); }
+	{ char ret; ret = __sync_fetch_and_and_1(vp1, v1); }
+	{ short ret; ret = __sync_fetch_and_and(vp2, v2); }
+	{ short ret; ret = __sync_fetch_and_and_2(vp2, v2); }
+	{ int ret; ret = __sync_fetch_and_and(vp4, v4); }
+	{ int ret; ret = __sync_fetch_and_and_4(vp4, v4); }
+	{ long long int ret; ret = __sync_fetch_and_and(vp8, v8); }
+	{ long long int ret; ret = __sync_fetch_and_and_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_fetch_and_and(vp16, v16); }
+	{ __int128 ret; ret = __sync_fetch_and_and_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_fetch_and_xor(vp1, v1); }
+	{ char ret; ret = __sync_fetch_and_xor_1(vp1, v1); }
+	{ short ret; ret = __sync_fetch_and_xor(vp2, v2); }
+	{ short ret; ret = __sync_fetch_and_xor_2(vp2, v2); }
+	{ int ret; ret = __sync_fetch_and_xor(vp4, v4); }
+	{ int ret; ret = __sync_fetch_and_xor_4(vp4, v4); }
+	{ long long int ret; ret = __sync_fetch_and_xor(vp8, v8); }
+	{ long long int ret; ret = __sync_fetch_and_xor_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_fetch_and_xor(vp16, v16); }
+	{ __int128 ret; ret = __sync_fetch_and_xor_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_fetch_and_nand(vp1, v1); }
+	{ char ret; ret = __sync_fetch_and_nand_1(vp1, v1); }
+	{ short ret; ret = __sync_fetch_and_nand(vp2, v2); }
+	{ short ret; ret = __sync_fetch_and_nand_2(vp2, v2); }
+	{ int ret; ret = __sync_fetch_and_nand(vp4, v4); }
+	{ int ret; ret = __sync_fetch_and_nand_4(vp4, v4); }
+	{ long long int ret; ret = __sync_fetch_and_nand(vp8, v8); }
+	{ long long int ret; ret = __sync_fetch_and_nand_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_fetch_and_nand(vp16, v16); }
+	{ __int128 ret; ret = __sync_fetch_and_nand_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_add_and_fetch(vp1, v1); }
+	{ char ret; ret = __sync_add_and_fetch_1(vp1, v1); }
+	{ short ret; ret = __sync_add_and_fetch(vp2, v2); }
+	{ short ret; ret = __sync_add_and_fetch_2(vp2, v2); }
+	{ int ret; ret = __sync_add_and_fetch(vp4, v4); }
+	{ int ret; ret = __sync_add_and_fetch_4(vp4, v4); }
+	{ long long int ret; ret = __sync_add_and_fetch(vp8, v8); }
+	{ long long int ret; ret = __sync_add_and_fetch_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_add_and_fetch(vp16, v16); }
+	{ __int128 ret; ret = __sync_add_and_fetch_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_sub_and_fetch(vp1, v1); }
+	{ char ret; ret = __sync_sub_and_fetch_1(vp1, v1); }
+	{ short ret; ret = __sync_sub_and_fetch(vp2, v2); }
+	{ short ret; ret = __sync_sub_and_fetch_2(vp2, v2); }
+	{ int ret; ret = __sync_sub_and_fetch(vp4, v4); }
+	{ int ret; ret = __sync_sub_and_fetch_4(vp4, v4); }
+	{ long long int ret; ret = __sync_sub_and_fetch(vp8, v8); }
+	{ long long int ret; ret = __sync_sub_and_fetch_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_sub_and_fetch(vp16, v16); }
+	{ __int128 ret; ret = __sync_sub_and_fetch_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_or_and_fetch(vp1, v1); }
+	{ char ret; ret = __sync_or_and_fetch_1(vp1, v1); }
+	{ short ret; ret = __sync_or_and_fetch(vp2, v2); }
+	{ short ret; ret = __sync_or_and_fetch_2(vp2, v2); }
+	{ int ret; ret = __sync_or_and_fetch(vp4, v4); }
+	{ int ret; ret = __sync_or_and_fetch_4(vp4, v4); }
+	{ long long int ret; ret = __sync_or_and_fetch(vp8, v8); }
+	{ long long int ret; ret = __sync_or_and_fetch_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_or_and_fetch(vp16, v16); }
+	{ __int128 ret; ret = __sync_or_and_fetch_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_and_and_fetch(vp1, v1); }
+	{ char ret; ret = __sync_and_and_fetch_1(vp1, v1); }
+	{ short ret; ret = __sync_and_and_fetch(vp2, v2); }
+	{ short ret; ret = __sync_and_and_fetch_2(vp2, v2); }
+	{ int ret; ret = __sync_and_and_fetch(vp4, v4); }
+	{ int ret; ret = __sync_and_and_fetch_4(vp4, v4); }
+	{ long long int ret; ret = __sync_and_and_fetch(vp8, v8); }
+	{ long long int ret; ret = __sync_and_and_fetch_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_and_and_fetch(vp16, v16); }
+	{ __int128 ret; ret = __sync_and_and_fetch_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_xor_and_fetch(vp1, v1); }
+	{ char ret; ret = __sync_xor_and_fetch_1(vp1, v1); }
+	{ short ret; ret = __sync_xor_and_fetch(vp2, v2); }
+	{ short ret; ret = __sync_xor_and_fetch_2(vp2, v2); }
+	{ int ret; ret = __sync_xor_and_fetch(vp4, v4); }
+	{ int ret; ret = __sync_xor_and_fetch_4(vp4, v4); }
+	{ long long int ret; ret = __sync_xor_and_fetch(vp8, v8); }
+	{ long long int ret; ret = __sync_xor_and_fetch_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_xor_and_fetch(vp16, v16); }
+	{ __int128 ret; ret = __sync_xor_and_fetch_16(vp16, v16); }
+	#endif
+
+	{ char ret; ret = __sync_nand_and_fetch(vp1, v1); }
+	{ char ret; ret = __sync_nand_and_fetch_1(vp1, v1); }
+	{ short ret; ret = __sync_nand_and_fetch(vp2, v2); }
+	{ short ret; ret = __sync_nand_and_fetch_2(vp2, v2); }
+	{ int ret; ret = __sync_nand_and_fetch(vp4, v4); }
+	{ int ret; ret = __sync_nand_and_fetch_4(vp4, v4); }
+	{ long long int ret; ret = __sync_nand_and_fetch(vp8, v8); }
+	{ long long int ret; ret = __sync_nand_and_fetch_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_nand_and_fetch(vp16, v16); }
+	{ __int128 ret; ret = __sync_nand_and_fetch_16(vp16, v16); }
+	#endif
+
+	{ _Bool ret; ret = __sync_bool_compare_and_swap(vp1, v1, v1); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap_1(vp1, v1, v1); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap(vp2, v2, v2); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap_2(vp2, v2, v2); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap(vp4, v4, v4); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap_4(vp4, v4, v4); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap(vp8, v8, v8); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap_8(vp8, v8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ _Bool ret; ret = __sync_bool_compare_and_swap(vp16, v16, v16); }
+	{ _Bool ret; ret = __sync_bool_compare_and_swap_16(vp16, v16,v16); }
+	#endif
+
+	{ char ret; ret = __sync_val_compare_and_swap(vp1, v1, v1); }
+	{ char ret; ret = __sync_val_compare_and_swap_1(vp1, v1, v1); }
+	{ short ret; ret = __sync_val_compare_and_swap(vp2, v2, v2); }
+	{ short ret; ret = __sync_val_compare_and_swap_2(vp2, v2, v2); }
+	{ int ret; ret = __sync_val_compare_and_swap(vp4, v4, v4); }
+	{ int ret; ret = __sync_val_compare_and_swap_4(vp4, v4, v4); }
+	{ long long int ret; ret = __sync_val_compare_and_swap(vp8, v8, v8); }
+	{ long long int ret; ret = __sync_val_compare_and_swap_8(vp8, v8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_val_compare_and_swap(vp16, v16, v16); }
+	{ __int128 ret; ret = __sync_val_compare_and_swap_16(vp16, v16,v16); }
+	#endif
+
+	{ char ret; ret = __sync_lock_test_and_set(vp1, v1); }
+	{ char ret; ret = __sync_lock_test_and_set_1(vp1, v1); }
+	{ short ret; ret = __sync_lock_test_and_set(vp2, v2); }
+	{ short ret; ret = __sync_lock_test_and_set_2(vp2, v2); }
+	{ int ret; ret = __sync_lock_test_and_set(vp4, v4); }
+	{ int ret; ret = __sync_lock_test_and_set_4(vp4, v4); }
+	{ long long int ret; ret = __sync_lock_test_and_set(vp8, v8); }
+	{ long long int ret; ret = __sync_lock_test_and_set_8(vp8, v8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __sync_lock_test_and_set(vp16, v16); }
+	{ __int128 ret; ret = __sync_lock_test_and_set_16(vp16, v16); }
+	#endif
+
+	{ __sync_lock_release(vp1); }
+	{ __sync_lock_release_1(vp1); }
+	{ __sync_lock_release(vp2); }
+	{ __sync_lock_release_2(vp2); }
+	{ __sync_lock_release(vp4); }
+	{ __sync_lock_release_4(vp4); }
+	{ __sync_lock_release(vp8); }
+	{ __sync_lock_release_8(vp8); }
+	#if defined(__SIZEOF_INT128__)
+	{ __sync_lock_release(vp16); }
+	{ __sync_lock_release_16(vp16); }
+	#endif
+
+	{ __sync_synchronize(); }
+
+
+
+
+	{ _Bool ret; ret = __atomic_test_and_set(vpB, vB); }
+	{ _Bool ret; ret = __atomic_test_and_set(vp1, v1); }
+	{ __atomic_clear(vpB, vB); }
+	{ __atomic_clear(vp1, v1); }
+
+	{ char ret; ret = __atomic_exchange_n(vp1, &v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_exchange_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; __atomic_exchange(vp1, &v1, &ret, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_exchange_n(vp2, &v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_exchange_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; __atomic_exchange(vp2, &v2, &ret, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_exchange_n(vp4, &v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_exchange_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; __atomic_exchange(vp4, &v4, &ret, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_exchange_n(vp8, &v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_exchange_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; __atomic_exchange(vp8, &v8, &ret, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_exchange_n(vp16, &v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_exchange_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; __atomic_exchange(vp16, &v16, &ret, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_load_n(vp1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_load_1(vp1, __ATOMIC_SEQ_CST); }
+	{ char ret; __atomic_load(vp1, &ret, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_load_n(vp2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_load_2(vp2, __ATOMIC_SEQ_CST); }
+	{ short ret; __atomic_load(vp2, &ret, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_load_n(vp4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_load_4(vp4, __ATOMIC_SEQ_CST); }
+	{ int ret; __atomic_load(vp4, &ret, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_load_n(vp8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_load_8(vp8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; __atomic_load(vp8, &ret, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_load_n(vp16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_load_16(vp16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; __atomic_load(vp16, &ret, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ _Bool ret; ret = __atomic_compare_exchange_n(vp1, rp1, v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_1(vp1, rp1, v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange(vp1, rp1, &v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_n(vp2, rp2, v2, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_2(vp2, rp2, v2, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange(vp2, rp2, &v2, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_n(vp4, rp4, v4, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_4(vp4, rp4, v4, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange(vp4, rp4, &v4, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_n(vp8, rp8, v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_8(vp8, rp8, v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange(vp8, rp8, &v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ _Bool ret; ret = __atomic_compare_exchange_n(vp16, rp16, v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange_16(vp16, rp16, v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	{ _Bool ret; ret = __atomic_compare_exchange(vp16, rp16, &v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ __atomic_store_n(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ __atomic_store(vp1, &v1, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_n(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ __atomic_store(vp2, &v2, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_n(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ __atomic_store(vp4, &v4, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_n(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ __atomic_store(vp8, &v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __atomic_store_n(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __atomic_store_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __atomic_store(vp16, &v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_add_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_add_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_add_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_add_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_add_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_add_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_add_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_add_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_add_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_add_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_sub_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_sub_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_sub_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_sub_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_sub_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_sub_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_sub_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_sub_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_sub_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_sub_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_and_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_and_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_and_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_and_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_and_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_and_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_and_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_and_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_and_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_and_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_nand_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_nand_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_nand_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_nand_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_nand_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_nand_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_nand_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_nand_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_nand_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_nand_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_xor_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_xor_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_xor_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_xor_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_xor_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_xor_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_xor_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_xor_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_xor_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_xor_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_or_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_or_fetch_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_or_fetch(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_or_fetch_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_or_fetch(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_or_fetch_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_or_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_or_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_or_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_or_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_fetch_add(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_fetch_add_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_add(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_add_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_add(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_add_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_add(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_add_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_fetch_add(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_fetch_add_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_fetch_sub(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_fetch_sub_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_sub(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_sub_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_sub(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_sub_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_sub(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_sub_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_fetch_sub(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_fetch_sub_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_fetch_and(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_fetch_and_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_and(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_and_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_and(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_and_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_and(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_and_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_fetch_and(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_fetch_and_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_fetch_nand(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_fetch_nand_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_nand(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_nand_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_nand(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_nand_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_nand(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_nand_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_fetch_nand(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_fetch_nand_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_fetch_xor(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_fetch_xor_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_xor(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_xor_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_xor(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_xor_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_xor(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_xor_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_fetch_xor(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_fetch_xor_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ char ret; ret = __atomic_fetch_or(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ char ret; ret = __atomic_fetch_or_1(vp1, v1, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_or(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ short ret; ret = __atomic_fetch_or_2(vp2, v2, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_or(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ int ret; ret = __atomic_fetch_or_4(vp4, v4, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_or(vp8, v8, __ATOMIC_SEQ_CST); }
+	{ long long int ret; ret = __atomic_fetch_or_8(vp8, v8, __ATOMIC_SEQ_CST); }
+	#if defined(__SIZEOF_INT128__)
+	{ __int128 ret; ret = __atomic_fetch_or(vp16, v16, __ATOMIC_SEQ_CST); }
+	{ __int128 ret; ret = __atomic_fetch_or_16(vp16, v16, __ATOMIC_SEQ_CST); }
+	#endif
+
+	{ _Bool ret; ret = __atomic_always_lock_free(sizeof(int), vp4); }
+	{ _Bool ret; ret = __atomic_is_lock_free(sizeof(int), vp4); }
+	{ __atomic_thread_fence(__ATOMIC_SEQ_CST); }
+	{ __atomic_signal_fence(__ATOMIC_SEQ_CST); }
+}
+
+int main() {
+	return 0;
+}
Index: src/tests/concurrent/coroutineYield.c
===================================================================
--- src/tests/concurrent/coroutineYield.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/concurrent/coroutineYield.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -3,4 +3,13 @@
 #include <stdlib>
 #include <thread>
+#include <time>
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
 
 #ifdef LONG_TEST
Index: src/tests/concurrent/examples/datingService.c
===================================================================
--- src/tests/concurrent/examples/datingService.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/concurrent/examples/datingService.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -8,6 +8,6 @@
 // Created On       : Mon Oct 30 12:56:20 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar 14 22:48:40 2018
-// Update Count     : 23
+// Last Modified On : Sun May 27 09:05:18 2018
+// Update Count     : 26
 //
 
@@ -18,8 +18,8 @@
 #include <unistd.h>										// getpid
 
-enum { NoOfPairs = 20 };
+enum { CompCodes = 20 };								// number of compatibility codes
 
 monitor DatingService {
-	condition Girls[NoOfPairs], Boys[NoOfPairs];
+	condition Girls[CompCodes], Boys[CompCodes];
 	unsigned int GirlPhoneNo, BoyPhoneNo;
 }; // DatingService
@@ -47,6 +47,6 @@
 } // DatingService boy
 
-unsigned int girlck[NoOfPairs];
-unsigned int boyck[NoOfPairs];
+unsigned int girlck[CompCodes];
+unsigned int boyck[CompCodes];
 
 thread Girl {
@@ -88,20 +88,20 @@
 int main() {
 	DatingService TheExchange;
-	Girl * girls[NoOfPairs];
-	Boy  * boys[NoOfPairs];
+	Girl * girls[CompCodes];
+	Boy  * boys[CompCodes];
 
 	srandom( /*getpid()*/ 103 );
 
-	for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
+	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
 		girls[i] = new( &TheExchange, i, i );
-		boys[i]  = new( &TheExchange, i, NoOfPairs - ( i + 1 ) );
+		boys[i]  = new( &TheExchange, i, CompCodes - ( i + 1 ) );
 	} // for
 
-	for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
+	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
 		delete( boys[i] );
 		delete( girls[i] );
 	} // for
 
-	for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
+	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
 		if ( girlck[ boyck[i] ] != boyck[ girlck[i] ] ) abort();
 	} // for
Index: src/tests/concurrent/examples/matrixSum.c
===================================================================
--- src/tests/concurrent/examples/matrixSum.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/concurrent/examples/matrixSum.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -11,6 +11,6 @@
 // Created On       : Mon Oct  9 08:29:28 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  5 22:56:46 2017
-// Update Count     : 4
+// Last Modified On : Fri May 25 09:34:27 2018
+// Update Count     : 10
 // 
 
@@ -20,40 +20,39 @@
 
 thread Adder {
-    int * row, cols, * subtotal;						// communication
+	int * row, cols, & subtotal;						// communication
 };
 
 void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
-    adder.row = row;
-    adder.cols = cols;
-    adder.subtotal = &subtotal;
+	adder.[ row, cols ] = [ row, cols ];				// expression disallowed in multi-member access
+	&adder.subtotal = &subtotal;
 }
 
-void main( Adder & adder ) with( adder ) {
-    *subtotal = 0;
-    for ( int c = 0; c < cols; c += 1 ) {
-		*subtotal += row[c];
-    } // for
+void main( Adder & adder ) with( adder ) {				// thread starts here
+	subtotal = 0;
+	for ( int c = 0; c < cols; c += 1 ) {
+		subtotal += row[c];
+	} // for
 }
 
 int main() {
-    const int rows = 10, cols = 1000;
-    int matrix[rows][cols], subtotals[rows], total = 0;
-    processor p;										// extra kernel thread
+	const int rows = 10, cols = 1000;
+	int matrix[rows][cols], subtotals[rows], total = 0;
+	processor p;										// add kernel thread
 
-    for ( int r = 0; r < rows; r += 1 ) {
+	for ( int r = 0; r < rows; r += 1 ) {
 		for ( int c = 0; c < cols; c += 1 ) {
 			matrix[r][c] = 1;
 		} // for
-    } // for
-    Adder * adders[rows];
-    for ( int r = 0; r < rows; r += 1 ) {				// start threads to sum rows
+	} // for
+	Adder * adders[rows];
+	for ( int r = 0; r < rows; r += 1 ) {				// start threads to sum rows
 		adders[r] = &(*malloc()){ matrix[r], cols, subtotals[r] };
 //		adders[r] = new( matrix[r], cols, &subtotals[r] );
-    } // for
-    for ( int r = 0; r < rows; r += 1 ) {				// wait for threads to finish
+	} // for
+	for ( int r = 0; r < rows; r += 1 ) {				// wait for threads to finish
 		delete( adders[r] );
 		total += subtotals[r];							// total subtotals
-    } // for
-    sout | total | endl;
+	} // for
+	sout | total | endl;
 }
 
Index: src/tests/concurrent/signal/block.c
===================================================================
--- src/tests/concurrent/signal/block.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/concurrent/signal/block.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -14,10 +14,4 @@
 #include <time>
 
-#ifdef LONG_TEST
-static const unsigned long N = 150_000ul;
-#else
-static const unsigned long N = 5_000ul;
-#endif
-
 #ifndef PREEMPTION_RATE
 #define PREEMPTION_RATE 10`ms
@@ -27,4 +21,10 @@
 	return PREEMPTION_RATE;
 }
+
+#ifdef LONG_TEST
+static const unsigned long N = 150_000ul;
+#else
+static const unsigned long N = 5_000ul;
+#endif
 
 enum state_t { WAITED, SIGNAL, BARGE };
Index: src/tests/concurrent/signal/disjoint.c
===================================================================
--- src/tests/concurrent/signal/disjoint.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/concurrent/signal/disjoint.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -4,10 +4,4 @@
 #include <thread>
 #include <time>
-
-#ifdef LONG_TEST
-static const unsigned long N = 300_000ul;
-#else
-static const unsigned long N = 10_000ul;
-#endif
 
 #ifndef PREEMPTION_RATE
@@ -18,4 +12,10 @@
 	return PREEMPTION_RATE;
 }
+
+#ifdef LONG_TEST
+static const unsigned long N = 300_000ul;
+#else
+static const unsigned long N = 10_000ul;
+#endif
 
 enum state_t { WAIT, SIGNAL, BARGE };
Index: src/tests/concurrent/signal/wait.c
===================================================================
--- src/tests/concurrent/signal/wait.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/concurrent/signal/wait.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -12,10 +12,4 @@
 #include <time>
 
-#ifdef LONG_TEST
-static const unsigned long N = 375_000ul;
-#else
-static const unsigned long N = 2_500ul;
-#endif
-
 #ifndef PREEMPTION_RATE
 #define PREEMPTION_RATE 10`ms
@@ -25,4 +19,10 @@
 	return PREEMPTION_RATE;
 }
+
+#ifdef LONG_TEST
+static const unsigned long N = 375_000ul;
+#else
+static const unsigned long N = 2_500ul;
+#endif
 
 monitor global_t {};
Index: c/tests/io.c
===================================================================
--- src/tests/io.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ 	(revision )
@@ -1,184 +1,0 @@
-// 
-// 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.
-// 
-// io.c -- 
-// 
-// Author           : Peter A. Buhr
-// Created On       : Wed Mar  2 16:56:02 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jan 26 15:19:34 2018
-// Update Count     : 100
-// 
-
-#include <fstream>
-
-int main() {
-	_Bool b;											// basic types
-	char c;
-	signed char sc;
-	unsigned char usc;
-	short int si;
-	unsigned short int usi;
-	int i;
-	unsigned int ui;
-	long int li;
-	unsigned long int uli;
-	long long int lli;
-	unsigned long long int ulli;
-	float f;
-	double d;
-	long double ld;
-	float _Complex fc;
-	double _Complex dc;
-	long double _Complex ldc;
-	enum { size = 10 };
-	char s1[size], s2[size];
-
-	int x = 3, y = 5, z = 7;
-	sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
-	sout | 1 | 2 | 3 | endl;
-	sout | '1' | '2' | '3' | endl;
-	sout | 1 | "" | 2 | "" | 3 | endl;
-	sout | endl;
-
-	sout | "opening delimiters" | endl;
-	sout
-		 | "x (" | 1
-		 | "x [" | 2
-		 | "x {" | 3
-		 | "x =" | 4
-		 | "x $" | 5
-		 | "x £" | 6
-		 | "x ¥" | 7
-		 | "x ¡" | 8
-		 | "x ¿" | 9
-		 | "x «" | 10
-		 | endl | endl;
-
-	sout | "closing delimiters" | endl;
-	sout
-		 | 1 | ", x"
-		 | 2 | ". x"
-		 | 3 | "; x"
-		 | 4 | "! x"
-		 | 5 | "? x"
-		 | 6 | "% x"
-		 | 7 | "¢ x"
-		 | 8 | "» x"
-		 | 9 | ") x"
-		 | 10 | "] x"
-		 | 11 | "} x"
-		 | endl | endl;
-
-	sout | "opening/closing delimiters" | endl;
-	sout
-		 | "x`" | 1 | "`x'" | 2
-		 | "'x\"" | 3 | "\"x:" | 4
-		 | ":x " | 5 | " x\t" | 6
-		 | "\tx\f" | 7 | "\fx\v" | 8
-		 | "\vx\n" | 9 | "\nx\r" | 10
-		 | "\rx"
-		 | endl | endl;
-
-	sout | "override opening/closing delimiters" | endl;
-	sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
-	sout | endl;
-
-	ifstream in = { "io.data" };						// create / open file
-
-	sout | "input bacis types" | endl;
-	in	 | b											// boolean
-		 | c | sc | usc									// character
-		 | si | usi | i | ui | li | uli | lli | ulli	// integral
-		 | f | d | ld									// floating point
-		 | fc | dc | ldc								// floating-point complex
-		 | cstr( s1 ) | cstr( s2, size );				// C string, length unchecked and checked
-	sout | endl;
-
-	sout | "output basic types" | endl;
-	sout | b | endl										// boolean
-		 | c | ' ' | sc | ' ' | usc | endl				// character
-		 | si | usi | i | ui | li | uli | lli | ulli | endl // integral
-		 | f | d | ld | endl							// floating point
-		 | fc | dc | ldc | endl;						// complex
-	sout | endl;
-
-	sout | "tuples" | endl;
-	[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
-	sout | t1 | t2 | endl;								// print tuple
-	sout | endl;
-
-	sout | "toggle separator" | endl;
-	sout | f | "" | d | "" | ld | endl					// floating point without separator
-		 | sepDisable | fc | dc | ldc | endl			// complex without separator
-		 | fc | sepOn | dc | ldc | endl					// local separator add
-		 | sepEnable | fc | dc | ldc | endl				// complex with separator
-		 | fc | sepOff | dc | ldc | endl				// local separator removal
-		 | s1 | sepOff | s2 | endl						// local separator removal
-		 | s1 | "" | s2 | endl;							// local separator removal
-	sout | endl;
-
-	sout | "change separator" | endl;
-	sout | "from \"" | sep | "\"";
-	sepSet( sout, ", $" );								// change separator, maximum of 15 characters
-	sout | " to \"" | sep | "\"" | endl;
-	sout | f | d | ld | endl
-		 | fc | dc | ldc | endl
-		 | s1 | s2 | endl
-		 | t1 | t2 | endl;								// print tuple
-	sout | endl;
-	sout | "from \"" | sep | "\" ";
-	sepSet( sout, " " );								// restore separator
-	sout | "to \"" | sep | "\"" | endl;
-	sout | f | d | ld | endl
-		 | fc | dc | ldc | endl
-		 | s1 | s2 | endl
-		 | t1 | t2 | endl;								// print tuple
-	sout | endl;
-
-	sout | "check sepOn/sepOff" | endl;
-	sout | sepOn | 1 | 2 | 3 | sepOn | endl;			// no separator at start/end of line
-	sout | 1 | sepOff | 2 | 3 | endl;					// locally turn off implicit separator
-	sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n'; // no separator at start/end of line
-	sout | 1 | 2 | 3 | "\n\n" | sepOn;					// no separator at start of next line
-	sout | 1 | 2 | 3 | endl;
-	sout | endl;
-
-	sout | "check enable/disable" | endl;
-	sout | sepDisable | 1 | 2 | 3 | endl;				// globally turn off implicit separation
-	sout | 1 | sepOn | 2 | 3 | endl;					// locally turn on implicit separator
-	sout | sepEnable | 1 | 2 | 3 | endl | sepDisable;	// globally turn on/off implicit separation
-	sout | 1 | 2 | 3 | endl | sepEnable;				// globally turn on implicit separation
-	sout | 1 | 2 | 3 | sepOn | sepDisable | endl;		// ignore seperate at end of line
-	sout | 1 | 2 | 3 | sepOn | sepEnable | endl;		// separator at end of line
-	sout | 1 | 2 | 3 | endl;
-	sout | endl;
-
-//	sout | fmt( d, "%8.3f" ) || endl;
-//	sout | endl;
-
-	sepSetTuple( sout, " " );							// set tuple separator from ", " to " "
-	sout | t1 | t2 | " \"" | sep | "\"" | endl;
-	sepSetTuple( sout, ", " );							// reset tuple separator to ", "
-	sout | t1 | t2 | " \"" | sep | "\"" | endl;
-	sout | t1 | t2 | endl;								// print tuple
-	sout | endl;
-
-	[int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
-	sout | [ 3, 4, "a", 7.2 ] | endl;
-	sout | t3 | endl;
-	sepSetTuple( sout, " " );
-	sout | t3 | endl;
-	sout | sepOn | t3 | sepDisable | t3 | sepEnable | t3 | endl;
-	sepSet( sout, "^" );
-	sepSetTuple( sout, "-" );
-	sout | t3 | 3 | 4 | t3 | endl;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa io.c" //
-// End: //
Index: src/tests/io1.c
===================================================================
--- src/tests/io1.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/io1.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,73 @@
+// 
+// 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.
+// 
+// io1.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Mar  2 16:56:02 2016
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu May 24 21:17:56 2018
+// Update Count     : 104
+// 
+
+#include <fstream>
+
+int main() {
+	int x = 3, y = 5, z = 7;
+	sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
+	sout | 1 | 2 | 3 | endl;
+	sout | '1' | '2' | '3' | endl;
+	sout | 1 | "" | 2 | "" | 3 | endl;
+	sout | endl;
+
+	sout | "opening delimiters" | endl;
+	sout
+		 | "x (" | 1
+		 | "x [" | 2
+		 | "x {" | 3
+		 | "x =" | 4
+		 | "x $" | 5
+		 | "x £" | 6
+		 | "x ¥" | 7
+		 | "x ¡" | 8
+		 | "x ¿" | 9
+		 | "x «" | 10
+		 | endl | endl;
+
+	sout | "closing delimiters" | endl;
+	sout
+		 | 1 | ", x"
+		 | 2 | ". x"
+		 | 3 | "; x"
+		 | 4 | "! x"
+		 | 5 | "? x"
+		 | 6 | "% x"
+		 | 7 | "¢ x"
+		 | 8 | "» x"
+		 | 9 | ") x"
+		 | 10 | "] x"
+		 | 11 | "} x"
+		 | endl | endl;
+
+	sout | "opening/closing delimiters" | endl;
+	sout
+		 | "x`" | 1 | "`x'" | 2
+		 | "'x\"" | 3 | "\"x:" | 4
+		 | ":x " | 5 | " x\t" | 6
+		 | "\tx\f" | 7 | "\fx\v" | 8
+		 | "\vx\n" | 9 | "\nx\r" | 10
+		 | "\rx"
+		 | endl | endl;
+
+	sout | "override opening/closing delimiters" | endl;
+	sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
+	sout | endl;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa io1.c" //
+// End: //
Index: src/tests/io2.c
===================================================================
--- src/tests/io2.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/io2.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,134 @@
+// 
+// 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.
+// 
+// io2.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Mar  2 16:56:02 2016
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu May 24 21:17:41 2018
+// Update Count     : 103
+// 
+
+#include <fstream>
+
+int main() {
+	_Bool b;											// basic types
+	char c;
+	signed char sc;
+	unsigned char usc;
+	short int si;
+	unsigned short int usi;
+	int i;
+	unsigned int ui;
+	long int li;
+	unsigned long int uli;
+	long long int lli;
+	unsigned long long int ulli;
+	float f;
+	double d;
+	long double ld;
+	float _Complex fc;
+	double _Complex dc;
+	long double _Complex ldc;
+	enum { size = 10 };
+	char s1[size], s2[size];
+
+	ifstream in = { "io.data" };						// create / open file
+
+	sout | "input bacis types" | endl;
+	in	 | b											// boolean
+		 | c | sc | usc									// character
+		 | si | usi | i | ui | li | uli | lli | ulli	// integral
+		 | f | d | ld									// floating point
+		 | fc | dc | ldc								// floating-point complex
+		 | cstr( s1 ) | cstr( s2, size );				// C string, length unchecked and checked
+	sout | endl;
+
+	sout | "output basic types" | endl;
+	sout | b | endl										// boolean
+		 | c | ' ' | sc | ' ' | usc | endl				// character
+		 | si | usi | i | ui | li | uli | lli | ulli | endl // integral
+		 | f | d | ld | endl							// floating point
+		 | fc | dc | ldc | endl;						// complex
+	sout | endl;
+
+	sout | "tuples" | endl;
+	[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
+	sout | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	sout | "toggle separator" | endl;
+	sout | f | "" | d | "" | ld | endl					// floating point without separator
+		 | sepDisable | fc | dc | ldc | endl			// complex without separator
+		 | fc | sepOn | dc | ldc | endl					// local separator add
+		 | sepEnable | fc | dc | ldc | endl				// complex with separator
+		 | fc | sepOff | dc | ldc | endl				// local separator removal
+		 | s1 | sepOff | s2 | endl						// local separator removal
+		 | s1 | "" | s2 | endl;							// local separator removal
+	sout | endl;
+
+	sout | "change separator" | endl;
+	sout | "from \"" | sep | "\"";
+	sepSet( sout, ", $" );								// change separator, maximum of 15 characters
+	sout | " to \"" | sep | "\"" | endl;
+	sout | f | d | ld | endl
+		 | fc | dc | ldc | endl
+		 | s1 | s2 | endl
+		 | t1 | t2 | endl;								// print tuple
+	sout | endl;
+	sout | "from \"" | sep | "\" ";
+	sepSet( sout, " " );								// restore separator
+	sout | "to \"" | sep | "\"" | endl;
+	sout | f | d | ld | endl
+		 | fc | dc | ldc | endl
+		 | s1 | s2 | endl
+		 | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	sout | "check sepOn/sepOff" | endl;
+	sout | sepOn | 1 | 2 | 3 | sepOn | endl;			// no separator at start/end of line
+	sout | 1 | sepOff | 2 | 3 | endl;					// locally turn off implicit separator
+	sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n'; // no separator at start/end of line
+	sout | 1 | 2 | 3 | "\n\n" | sepOn;					// no separator at start of next line
+	sout | 1 | 2 | 3 | endl;
+	sout | endl;
+
+	sout | "check enable/disable" | endl;
+	sout | sepDisable | 1 | 2 | 3 | endl;				// globally turn off implicit separation
+	sout | 1 | sepOn | 2 | 3 | endl;					// locally turn on implicit separator
+	sout | sepEnable | 1 | 2 | 3 | endl | sepDisable;	// globally turn on/off implicit separation
+	sout | 1 | 2 | 3 | endl | sepEnable;				// globally turn on implicit separation
+	sout | 1 | 2 | 3 | sepOn | sepDisable | endl;		// ignore seperate at end of line
+	sout | 1 | 2 | 3 | sepOn | sepEnable | endl;		// separator at end of line
+	sout | 1 | 2 | 3 | endl;
+	sout | endl;
+
+//	sout | fmt( d, "%8.3f" ) || endl;
+//	sout | endl;
+
+	sepSetTuple( sout, " " );							// set tuple separator from ", " to " "
+	sout | t1 | t2 | " \"" | sep | "\"" | endl;
+	sepSetTuple( sout, ", " );							// reset tuple separator to ", "
+	sout | t1 | t2 | " \"" | sep | "\"" | endl;
+	sout | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	[int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
+	sout | [ 3, 4, "a", 7.2 ] | endl;
+	sout | t3 | endl;
+	sepSetTuple( sout, " " );
+	sout | t3 | endl;
+	sout | sepOn | t3 | sepDisable | t3 | sepEnable | t3 | endl;
+	sepSet( sout, "^" );
+	sepSetTuple( sout, "-" );
+	sout | t3 | 3 | 4 | t3 | endl;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa io2.c" //
+// End: //
Index: src/tests/math1.c
===================================================================
--- src/tests/math1.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/math1.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 11 15:16:41 2017
-// Update Count     : 84
+// Last Modified On : Thu May 24 21:01:15 2018
+// Update Count     : 85
 // 
 
@@ -48,17 +48,4 @@
     sout | "\\" | b | b \ e | endl;
     sout | "\\" | 'a' \ 3u | 2 \ 8u | 4 \ 3u | -4 \ 3u | 4 \ -3 | -4 \ -3 | 4.0 \ 2.1 | (1.0f+2.0fi) \ (3.0f+2.0fi) | endl;
-
-	//---------------------- Logarithm ----------------------
-
-	sout | "log:" | log( 1.0F ) | log( 1.0D ) | log( 1.0L ) | log( 1.0F+1.0FI ) | log( 1.0D+1.0DI ) | log( 1.0DL+1.0LI ) | endl;
-	sout | "log2:" | log2( 8.0F ) | log2( 8.0D ) | log2( 8.0L ) | endl;
-	sout | "log10:" | log10( 100.0F ) | log10( 100.0D ) | log10( 100.0L ) | endl;
-	sout | "log1p:" | log1p( 1.0F ) | log1p( 1.0D ) | log1p( 1.0L ) | endl;
-	sout | "ilogb:" | ilogb( 1.0F ) | ilogb( 1.0D ) | ilogb( 1.0L ) | endl;
-	sout | "logb:" | logb( 8.0F ) | logb( 8.0D ) | logb( 8.0L ) | endl;
-
-	sout | "sqrt:" | sqrt( 1.0F ) | sqrt( 1.0D ) | sqrt( 1.0L ) | sqrt( 1.0F+1.0FI ) | sqrt( 1.0D+1.0DI ) | sqrt( 1.0DL+1.0LI ) | endl;
-	sout | "cbrt:" | cbrt( 27.0F ) | cbrt( 27.0D ) | cbrt( 27.0L ) | endl;
-	sout | "hypot:" | hypot( 1.0F, -1.0F ) | hypot( 1.0D, -1.0D ) | hypot( 1.0L, -1.0L ) | endl;
 } // main
 
Index: src/tests/math2.c
===================================================================
--- src/tests/math2.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/math2.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 11 15:40:04 2017
-// Update Count     : 81
+// Last Modified On : Thu May 24 21:06:10 2018
+// Update Count     : 82
 // 
 
@@ -21,4 +21,17 @@
 	double d;
 	long double l;
+
+	//---------------------- Logarithm ----------------------
+
+	sout | "log:" | log( 1.0F ) | log( 1.0D ) | log( 1.0L ) | log( 1.0F+1.0FI ) | log( 1.0D+1.0DI ) | log( 1.0DL+1.0LI ) | endl;
+	sout | "log2:" | log2( 8.0F ) | log2( 8.0D ) | log2( 8.0L ) | endl;
+	sout | "log10:" | log10( 100.0F ) | log10( 100.0D ) | log10( 100.0L ) | endl;
+	sout | "log1p:" | log1p( 1.0F ) | log1p( 1.0D ) | log1p( 1.0L ) | endl;
+	sout | "ilogb:" | ilogb( 1.0F ) | ilogb( 1.0D ) | ilogb( 1.0L ) | endl;
+	sout | "logb:" | logb( 8.0F ) | logb( 8.0D ) | logb( 8.0L ) | endl;
+
+	sout | "sqrt:" | sqrt( 1.0F ) | sqrt( 1.0D ) | sqrt( 1.0L ) | sqrt( 1.0F+1.0FI ) | sqrt( 1.0D+1.0DI ) | sqrt( 1.0DL+1.0LI ) | endl;
+	sout | "cbrt:" | cbrt( 27.0F ) | cbrt( 27.0D ) | cbrt( 27.0L ) | endl;
+	sout | "hypot:" | hypot( 1.0F, -1.0F ) | hypot( 1.0D, -1.0D ) | hypot( 1.0L, -1.0L ) | endl;
 
 	//---------------------- Trigonometric ----------------------
@@ -32,27 +45,4 @@
 	sout | "atan2:" | atan2( 1.0F, 1.0F ) | atan2( 1.0D, 1.0D ) | atan2( 1.0L, 1.0L );
 	sout | "atan:" | atan( 1.0F, 1.0F ) | atan( 1.0D, 1.0D ) | atan( 1.0L, 1.0L ) | endl;
-
-	//---------------------- Hyperbolic ----------------------
-
-	sout | "sinh:" | sinh( 1.0F ) | sinh( 1.0D ) | sinh( 1.0L ) | sinh( 1.0F+1.0FI ) | sinh( 1.0D+1.0DI ) | sinh( 1.0DL+1.0LI ) | endl;
-	sout | "cosh:" | cosh( 1.0F ) | cosh( 1.0D ) | cosh( 1.0L ) | cosh( 1.0F+1.0FI ) | cosh( 1.0D+1.0DI ) | cosh( 1.0DL+1.0LI ) | endl;
-	sout | "tanh:" | tanh( 1.0F ) | tanh( 1.0D ) | tanh( 1.0L ) | tanh( 1.0F+1.0FI ) | tanh( 1.0D+1.0DI ) | tanh( 1.0DL+1.0LI ) | endl;
-	sout | "acosh:" | acosh( 1.0F ) | acosh( 1.0D ) | acosh( 1.0L ) | acosh( 1.0F+1.0FI ) | acosh( 1.0D+1.0DI ) | acosh( 1.0DL+1.0LI ) | endl;
-	sout | "asinh:" | asinh( 1.0F ) | asinh( 1.0D ) | asinh( 1.0L ) | asinh( 1.0F+1.0FI ) | asinh( 1.0D+1.0DI ) | asinh( 1.0DL+1.0LI ) | endl;
-	sout | "atanh:" | atanh( 1.0F ) | atanh( 1.0D ) | atanh( 1.0L ) | atanh( 1.0F+1.0FI ) | atanh( 1.0D+1.0DI ) | atanh( 1.0DL+1.0LI ) | endl;
-
-	//---------------------- Error / Gamma ----------------------
-
-	sout | "erf:" | erf( 1.0F ) | erf( 1.0D ) | erf( 1.0L ) | endl;
-	sout | "erfc:" | erfc( 1.0F ) | erfc( 1.0D ) | erfc( 1.0L ) | endl;
-	sout | "lgamma:" | lgamma( 4.0F ) | lgamma( 4.0D ) | lgamma( 4.0L ) | endl;
-	int sign;
-	f = lgamma( 4.0F, &sign );
-	sout | "lgamma:" | f | sign;
-	d = lgamma( 4.0D, &sign );
-	sout | d | sign;
-	l = lgamma( 4.0L, &sign );
-	sout | l | sign | endl;
-	sout | "tgamma:" | tgamma( 4.0F ) | tgamma( 4.0D ) | tgamma( 4.0L ) | endl;
 } // main
 
Index: src/tests/math3.c
===================================================================
--- src/tests/math3.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/math3.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 11 15:40:03 2017
-// Update Count     : 81
+// Last Modified On : Thu May 24 21:06:12 2018
+// Update Count     : 82
 // 
 
@@ -22,47 +22,26 @@
 	long double l;
 
-	//---------------------- Nearest Integer ----------------------
+	//---------------------- Hyperbolic ----------------------
 
-	sout | "floor:" | floor( 1.2F ) | floor( 1.2D ) | floor( 1.2L ) | endl;
-	sout | "ceil:" | ceil( 1.6F ) | ceil( 1.6D ) | ceil( 1.6L ) | endl;
-	sout | "trunc:" | trunc( 3.5F ) | trunc( 3.5D ) | trunc( 3.5L ) | endl;
-	sout | "rint:" | (float)rint( 1.5F ) | (double)rint( 1.5D ) | (long double)rint( 1.5L ) | endl;
-	sout | "rint:" | (long int)rint( 1.5F ) | (long int)rint( 1.5D ) | (long int)rint( 1.5L ) | endl;
-	sout | "rint:" | (long long int)rint( 1.5F ) | (long long int)rint( 1.5D ) | (long long int)rint( 1.5L ) | endl;
-	sout | "lrint:" | lrint( 1.5F ) | lrint( 1.5D ) | lrint( 1.5L ) | endl;
-	sout | "llrint:" | llrint( 1.5F ) | llrint( 1.5D ) | llrint( 1.5L ) | endl;
-	sout | "nearbyint:" | nearbyint( 3.5F ) | nearbyint( 3.5D ) | nearbyint( 3.5L ) | endl;
-	sout | "round:" | (float)round( 1.5F ) | (double)round( 1.5D ) | (long double)round( 1.5L ) | endl;
-	sout | "round:" | (long int)round( 1.5F ) | (long int)round( 1.5D ) | (long int)round( 1.5L ) | endl;
-	sout | "round:" | (long long int)round( 1.5F ) | (long long int)round( 1.5D ) | (long long int)round( 1.5L ) | endl;
-	sout | "lround:" | lround( 1.5F ) | lround( 1.5D ) | lround( 1.5L ) | endl;
-	sout | "llround:" | llround( 1.5F ) | llround( 1.5D ) | llround( 1.5L ) | endl;
+	sout | "sinh:" | sinh( 1.0F ) | sinh( 1.0D ) | sinh( 1.0L ) | sinh( 1.0F+1.0FI ) | sinh( 1.0D+1.0DI ) | sinh( 1.0DL+1.0LI ) | endl;
+	sout | "cosh:" | cosh( 1.0F ) | cosh( 1.0D ) | cosh( 1.0L ) | cosh( 1.0F+1.0FI ) | cosh( 1.0D+1.0DI ) | cosh( 1.0DL+1.0LI ) | endl;
+	sout | "tanh:" | tanh( 1.0F ) | tanh( 1.0D ) | tanh( 1.0L ) | tanh( 1.0F+1.0FI ) | tanh( 1.0D+1.0DI ) | tanh( 1.0DL+1.0LI ) | endl;
+	sout | "acosh:" | acosh( 1.0F ) | acosh( 1.0D ) | acosh( 1.0L ) | acosh( 1.0F+1.0FI ) | acosh( 1.0D+1.0DI ) | acosh( 1.0DL+1.0LI ) | endl;
+	sout | "asinh:" | asinh( 1.0F ) | asinh( 1.0D ) | asinh( 1.0L ) | asinh( 1.0F+1.0FI ) | asinh( 1.0D+1.0DI ) | asinh( 1.0DL+1.0LI ) | endl;
+	sout | "atanh:" | atanh( 1.0F ) | atanh( 1.0D ) | atanh( 1.0L ) | atanh( 1.0F+1.0FI ) | atanh( 1.0D+1.0DI ) | atanh( 1.0DL+1.0LI ) | endl;
 
-	//---------------------- Manipulation ----------------------
+	//---------------------- Error / Gamma ----------------------
 
-	sout | "copysign:" | copysign( 1.0F, -1.0F ) | copysign( 1.0D, -1.0D ) | copysign( 1.0L, -1.0L ) | endl;
-	int exp;
-	f = frexp( 4.0F, &exp );
-	sout | "frexp:" | f | exp;
-	d = frexp( 4.0D, &exp );
-	sout | d | exp;
-	l = frexp( 4.0L, &exp );
-	sout | l | exp | endl;
-	sout | "ldexp:" | ldexp( 2.0F, 2 ) | ldexp( 2.0D, 2 ) | ldexp( 2.0L, 2 ) | endl;
-	float fi;
-	double di;
-	long double ldi;
-	f = modf( 2.3F, &fi );
-	sout | "modf:" | fi | f;
-	d = modf( 2.3D, &di );
-	sout | di | d;
-	l = modf( 2.3L, &ldi );
-	sout | ldi | l | endl;
-	sout | "modf:" | modf( 2.3F ) | modf( 2.3D ) | modf( 2.3L ) | endl;
-	sout | "nextafter:" | nextafter( 2.0F, 3.0F ) | nextafter( 2.0D, 3.0D ) | nextafter( 2.0L, 3.0L ) | endl;
-	sout | "nexttoward:" | nexttoward( 2.0F, 3.0F ) | nexttoward( 2.0D, 3.0D ) | nexttoward( 2.0L, 3.0L ) | endl;
-
-	sout | "scalbn:" | scalbn( 2.0F, 3 ) | scalbn( 2.0D, 3 ) | scalbn( 2.0L, 3 ) | endl;
-	sout | "scalbln:" | scalbln( 2.0F, 3L ) | scalbln( 2.0D, 3L ) | scalbln( 2.0L, 3L ) | endl;
+	sout | "erf:" | erf( 1.0F ) | erf( 1.0D ) | erf( 1.0L ) | endl;
+	sout | "erfc:" | erfc( 1.0F ) | erfc( 1.0D ) | erfc( 1.0L ) | endl;
+	sout | "lgamma:" | lgamma( 4.0F ) | lgamma( 4.0D ) | lgamma( 4.0L ) | endl;
+	int sign;
+	f = lgamma( 4.0F, &sign );
+	sout | "lgamma:" | f | sign;
+	d = lgamma( 4.0D, &sign );
+	sout | d | sign;
+	l = lgamma( 4.0L, &sign );
+	sout | l | sign | endl;
+	sout | "tgamma:" | tgamma( 4.0F ) | tgamma( 4.0D ) | tgamma( 4.0L ) | endl;
 } // main
 
Index: src/tests/math4.c
===================================================================
--- src/tests/math4.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
+++ src/tests/math4.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -0,0 +1,72 @@
+// 
+// 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.
+// 
+// math4.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Thu May 24 20:56:54 2018
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu May 24 20:58:06 2018
+// Update Count     : 2
+// 
+
+#include <fstream>
+#include <math>
+
+int main( void ) {
+	float f;
+	double d;
+	long double l;
+
+	//---------------------- Nearest Integer ----------------------
+
+	sout | "floor:" | floor( 1.2F ) | floor( 1.2D ) | floor( 1.2L ) | endl;
+	sout | "ceil:" | ceil( 1.6F ) | ceil( 1.6D ) | ceil( 1.6L ) | endl;
+	sout | "trunc:" | trunc( 3.5F ) | trunc( 3.5D ) | trunc( 3.5L ) | endl;
+	sout | "rint:" | (float)rint( 1.5F ) | (double)rint( 1.5D ) | (long double)rint( 1.5L ) | endl;
+	sout | "rint:" | (long int)rint( 1.5F ) | (long int)rint( 1.5D ) | (long int)rint( 1.5L ) | endl;
+	sout | "rint:" | (long long int)rint( 1.5F ) | (long long int)rint( 1.5D ) | (long long int)rint( 1.5L ) | endl;
+	sout | "lrint:" | lrint( 1.5F ) | lrint( 1.5D ) | lrint( 1.5L ) | endl;
+	sout | "llrint:" | llrint( 1.5F ) | llrint( 1.5D ) | llrint( 1.5L ) | endl;
+	sout | "nearbyint:" | nearbyint( 3.5F ) | nearbyint( 3.5D ) | nearbyint( 3.5L ) | endl;
+	sout | "round:" | (float)round( 1.5F ) | (double)round( 1.5D ) | (long double)round( 1.5L ) | endl;
+	sout | "round:" | (long int)round( 1.5F ) | (long int)round( 1.5D ) | (long int)round( 1.5L ) | endl;
+	sout | "round:" | (long long int)round( 1.5F ) | (long long int)round( 1.5D ) | (long long int)round( 1.5L ) | endl;
+	sout | "lround:" | lround( 1.5F ) | lround( 1.5D ) | lround( 1.5L ) | endl;
+	sout | "llround:" | llround( 1.5F ) | llround( 1.5D ) | llround( 1.5L ) | endl;
+
+	//---------------------- Manipulation ----------------------
+
+	sout | "copysign:" | copysign( 1.0F, -1.0F ) | copysign( 1.0D, -1.0D ) | copysign( 1.0L, -1.0L ) | endl;
+	int exp;
+	f = frexp( 4.0F, &exp );
+	sout | "frexp:" | f | exp;
+	d = frexp( 4.0D, &exp );
+	sout | d | exp;
+	l = frexp( 4.0L, &exp );
+	sout | l | exp | endl;
+	sout | "ldexp:" | ldexp( 2.0F, 2 ) | ldexp( 2.0D, 2 ) | ldexp( 2.0L, 2 ) | endl;
+	float fi;
+	double di;
+	long double ldi;
+	f = modf( 2.3F, &fi );
+	sout | "modf:" | fi | f;
+	d = modf( 2.3D, &di );
+	sout | di | d;
+	l = modf( 2.3L, &ldi );
+	sout | ldi | l | endl;
+	sout | "modf:" | modf( 2.3F ) | modf( 2.3D ) | modf( 2.3L ) | endl;
+	sout | "nextafter:" | nextafter( 2.0F, 3.0F ) | nextafter( 2.0D, 3.0D ) | nextafter( 2.0L, 3.0L ) | endl;
+	sout | "nexttoward:" | nexttoward( 2.0F, 3.0F ) | nexttoward( 2.0D, 3.0D ) | nexttoward( 2.0L, 3.0L ) | endl;
+
+	sout | "scalbn:" | scalbn( 2.0F, 3 ) | scalbn( 2.0D, 3 ) | scalbn( 2.0L, 3 ) | endl;
+	sout | "scalbln:" | scalbln( 2.0F, 3L ) | scalbln( 2.0D, 3L ) | scalbln( 2.0L, 3L ) | endl;
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa math3.c" //
+// End: //
Index: src/tests/preempt_longrun/Makefile.am
===================================================================
--- src/tests/preempt_longrun/Makefile.am	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/Makefile.am	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -17,5 +17,5 @@
 repeats=10
 max_time=600
-preempt=1_000ul
+preempt=10ul\`ms
 debug=-debug
 
Index: src/tests/preempt_longrun/Makefile.in
===================================================================
--- src/tests/preempt_longrun/Makefile.in	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/Makefile.in	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -450,5 +450,5 @@
 repeats = 10
 max_time = 600
-preempt = 1_000ul
+preempt = 10ul\`ms
 debug = -debug
 REPEAT = ${abs_top_srcdir}/tools/repeat
Index: src/tests/preempt_longrun/create.c
===================================================================
--- src/tests/preempt_longrun/create.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/create.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,9 +1,8 @@
 #include <kernel>
 #include <thread>
-
-static const unsigned long N = 60_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -11,4 +10,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N = 60_000ul;
 
 thread worker_t {};
Index: src/tests/preempt_longrun/enter.c
===================================================================
--- src/tests/preempt_longrun/enter.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/enter.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -2,9 +2,8 @@
 #include <monitor>
 #include <thread>
-
-static const unsigned long N  = 2_100_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -12,4 +11,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N  = 2_100_000ul;
 
 monitor mon_t {};
Index: src/tests/preempt_longrun/enter3.c
===================================================================
--- src/tests/preempt_longrun/enter3.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/enter3.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -2,9 +2,8 @@
 #include <monitor>
 #include <thread>
-
-static const unsigned long N  = 500_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -12,4 +11,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N  = 500_000ul;
 
 monitor mon_t {};
Index: src/tests/preempt_longrun/processor.c
===================================================================
--- src/tests/preempt_longrun/processor.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/processor.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,9 +1,8 @@
 #include <kernel>
 #include <thread>
-
-static const unsigned long N = 5_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -11,4 +10,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N = 5_000ul;
 
 int main(int argc, char* argv[]) {
Index: src/tests/preempt_longrun/stack.c
===================================================================
--- src/tests/preempt_longrun/stack.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/stack.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,9 +1,9 @@
 #include <kernel>
+#include <math>
 #include <thread>
-
-#include <math>
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
Index: src/tests/preempt_longrun/yield.c
===================================================================
--- src/tests/preempt_longrun/yield.c	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/preempt_longrun/yield.c	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -1,4 +1,13 @@
 #include <kernel>
 #include <thread>
+#include <time>
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
 
 #ifdef LONG_TEST
@@ -7,12 +16,4 @@
 static const unsigned long N = 325_000ul;
 #endif
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
 
 thread worker_t {};
Index: src/tests/test.py
===================================================================
--- src/tests/test.py	(revision 96812c08a8de9308f7cd2aa6c43b95d71bf1bba1)
+++ src/tests/test.py	(revision 054514d366b6a7a6863d673a9c760baa03661f21)
@@ -78,9 +78,4 @@
 			else :
 				print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr)
-
-	# make sure we have at least some test to run
-	if not tests :
-		print('ERROR: No valid test to run', file=sys.stderr)
-		sys.exit(1)
 
 	return tests
@@ -266,4 +261,10 @@
 		tests = validTests( options )
 
+	# make sure we have at least some test to run
+	if not tests :
+		print('ERROR: No valid test to run', file=sys.stderr)
+		sys.exit(1)
+
+
 	# sort the test alphabetically for convenience
 	tests.sort(key=lambda t: (t.arch if t.arch else '') + t.target())
