Index: doc/bibliography/pl.bib
===================================================================
--- doc/bibliography/pl.bib	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/bibliography/pl.bib	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -6687,5 +6687,5 @@
     contributer	= {pabuhr@plg},
     author	= {{TIOBE Index}},
-    year	= {March 2017},
+    year	= {February 2018},
     url		= {http://www.tiobe.com/tiobe_index},
 }
Index: doc/papers/general/Paper.tex
===================================================================
--- doc/papers/general/Paper.tex	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/papers/general/Paper.tex	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -13,4 +13,6 @@
 \usepackage{pslatex}						% reduce size of san serif font
 \usepackage[plainpages=false,pdfpagelabels,pdfpagemode=UseNone,pagebackref=true,breaklinks=true,colorlinks=true,linkcolor=blue,citecolor=blue,urlcolor=blue]{hyperref}
+\urlstyle{sf}
+\usepackage{breakurl}
 
 \setlength{\textheight}{9in}
@@ -199,5 +201,5 @@
 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems to hobby projects.
 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
-The TIOBE~\cite{TIOBE} ranks the top 5 most popular programming languages as: Java 16\%, \Textbf{C 7\%}, \Textbf{\CC 5\%}, \Csharp 4\%, Python 4\% = 36\%, where the next 50 languages are less than 3\% each with a long tail.
+The TIOBE~\cite{TIOBE} ranks the top 5 most \emph{popular} programming languages as: Java 15\%, \Textbf{C 12\%}, \Textbf{\CC 5.5\%}, Python 5\%, \Csharp 4.5\% = 42\%, where the next 50 languages are less than 4\% each with a long tail.
 The top 3 rankings over the past 30 years are:
 \begin{center}
@@ -205,8 +207,8 @@
 \lstDeleteShortInline@%
 \begin{tabular}{@{}rccccccc@{}}
-		& 2017	& 2012	& 2007	& 2002	& 1997	& 1992	& 1987		\\ \hline
-Java	& 1		& 1		& 1		& 1		& 12	& -		& -			\\
-\Textbf{C}	& \Textbf{2}& \Textbf{2}& \Textbf{2}& \Textbf{2}& \Textbf{1}& \Textbf{1}& \Textbf{1}	\\
-\CC		& 3		& 3		& 3		& 3		& 2		& 2		& 4			\\
+		& 2018	& 2013	& 2008	& 2003	& 1998	& 1993	& 1988	\\ \hline
+Java	& 1		& 2		& 1		& 1		& 18	& -		& -		\\
+\Textbf{C}& \Textbf{2} & \Textbf{1} & \Textbf{2} & \Textbf{2} & \Textbf{1} & \Textbf{1} & \Textbf{1} \\
+\CC		& 3		& 4		& 3		& 3		& 2		& 2		& 5		\\
 \end{tabular}
 \lstMakeShortInline@%
@@ -227,15 +229,21 @@
 \CFA is currently implemented as a source-to-source translator from \CFA to the gcc-dialect of C~\cite{GCCExtensions}, allowing it to leverage the portability and code optimizations provided by gcc, meeting goals (1)--(3).
 Ultimately, a compiler is necessary for advanced features and optimal performance.
-
-This paper identifies shortcomings in existing approaches to generic and variadic data types in C-like languages and presents a design for generic and variadic types avoiding those shortcomings.
+All of the features discussed in this paper are working, unless a feature states it is a future feature for completion.
+
+
+\section{Polymorphic Functions}
+
+\CFA introduces both ad-hoc and parametric polymorphism to C, with a design originally formalized by Ditchfield~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
+Shortcomings are identified in existing approaches to generic and variadic data types in C-like languages and how these shortcomings are avoided in \CFA.
 Specifically, the solution is both reusable and type-checked, as well as conforming to the design goals of \CFA with ergonomic use of existing C abstractions.
-The new constructs are empirically compared with both standard C and \CC; the results show the new design is comparable in performance.
-
-\section{Polymorphic Functions}
-
-\CFA introduces both ad-hoc and parametric polymorphism to C, with a design originally formalized by Ditchfield~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
+The new constructs are empirically compared with C and \CC approaches via performance experiments in Section~\ref{sec:eval}.
+
 
 \subsection{Name Overloading}
-
+\label{s:NameOverloading}
+
+\begin{quote}
+There are only two hard things in Computer Science: cache invalidation and \emph{naming things} -- Phil Karlton
+\end{quote}
 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. 
 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable;
@@ -245,21 +253,23 @@
 
 \begin{cfa}
-int max(int a, int b) { return a < b ? b : a; }  // (1)
-double max(double a, double b) { return a < b ? b : a; }  // (2)
-
-int max = INT_MAX;     // (3)
-double max = DBL_MAX;  // (4)
-
-max(7, -max);   $\C{// uses (1) and (3), by matching int from constant 7}$
-max(max, 3.14); $\C{// uses (2) and (4), by matching double from constant 3.14}$
-
-//max(max, -max);  $\C{// ERROR: ambiguous}$
-int m = max(max, -max); $\C{// uses (1) once and (3) twice, by matching return type}$
-\end{cfa}
-
-\Celeven did add @_Generic@ expressions, which can be used in preprocessor macros to provide a form of ad-hoc polymorphism; however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading. 
+int max = 2147483647;						$\C[3.75in]{// (1)}$
+double max = 1.7976931348623157E+308;	$\C{// (2)}$
+int max( int a, int b ) { return a < b ? b : a; }  $\C{// (3)}$
+double max( double a, double b ) { return a < b ? b : a; }  $\C{// (4)}\CRT$
+max( 7, -max );								$\C{// uses (3) and (1), by matching int from constant 7}$
+max( max, 3.14 );							$\C{// uses (4) and (2), by matching double from constant 3.14}$
+max( max, -max );							$\C{// ERROR: ambiguous}$
+int m = max( max, -max );					$\C{// uses (3) and (1) twice, by matching return type}$
+\end{cfa}
+\CFA maximizes the ability to reuse names to aggressively address the naming problem.
+In some cases, hundreds of names can be reduced to tens, resulting in a significant cognitive reduction for a programmer.
+In the above, the name @max@ has a consistent meaning, and a programmer only needs to remember the single concept: maximum.
+To prevent significant ambiguities, \CFA uses the return type in selecting overloads, \eg in the assignment to @m@, the compiler use @m@'s type to unambiguously select the most appropriate call to function @max@ (as does Ada).
+As is shown later, there are a number of situations where \CFA takes advantage of available type information to disambiguate, where other programming languages generate ambiguities.
+
+\Celeven added @_Generic@ expressions, which can be used in preprocessor macros to provide a form of ad-hoc polymorphism; however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading. 
 The macro wrapping the generic expression imposes some limitations; as an example, it could not implement the example above, because the variables @max@ would collide with the functions @max@. 
 Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the functions dispatched to, which must all have distinct names.
-Though name-overloading removes a major use-case for @_Generic@ expressions, \CFA does implement @_Generic@ for backwards-compatibility purposes. \TODO{actually implement that}
+Though name-overloading removes a major use-case for @_Generic@ expressions, \CFA implements @_Generic@ for backwards-compatibility purposes. \TODO{actually implement that}
 
 % http://fanf.livejournal.com/144696.html
@@ -288,5 +298,5 @@
 For example, the function @twice@ can be defined using the \CFA syntax for operator overloading:
 \begin{cfa}
-forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x + x; }	$\C{// ? denotes operands}$
+forall( otype T `| { T ?+?(T, T); }` ) T twice( T x ) { return x `+` x; }	$\C{// ? denotes operands}$
 int val = twice( twice( 3.7 ) );
 \end{cfa}
@@ -343,5 +353,6 @@
 \begin{cfa}
 forall( otype T | { int ?<?( T, T ); } ) void qsort( const T * arr, size_t size ) { /* use C qsort */ }
-{	int ?<?( double x, double y ) { return x `>` y; }	$\C{// locally override behaviour}$
+{
+	int ?<?( double x, double y ) { return x `>` y; }	$\C{// locally override behaviour}$
 	qsort( vals, size );					$\C{// descending sort}$
 }
@@ -414,10 +425,10 @@
 \section{Generic Types}
 
-One of the known shortcomings of standard C is that it does not provide reusable type-safe abstractions for generic data structures and algorithms.
+A significant shortcoming of standard C is the lack of reusable type-safe abstractions for generic data structures and algorithms.
 Broadly speaking, there are three approaches to implement abstract data-structures in C.
 One approach is to write bespoke data-structures for each context in which they are needed.
 While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures.
-A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@; an approach which does allow reuse of code for common functionality.
-However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that would not otherwise be needed.
+A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@, which allows reuse of code with common functionality.
+However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is not otherwise needed.
 A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type-checked, but errors may be difficult to interpret.
 Furthermore, writing and using preprocessor macros can be unnatural and inflexible.
@@ -434,13 +445,13 @@
 };
 forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; }
-forall( dtype F, otype T ) T value_p( pair( F *, T * ) p ) { return * p.second; }
+forall( dtype F, otype T ) T value( pair( F *, T * ) p ) { return *p.second; }
 
 pair( const char *, int ) p = { "magic", 42 };
-int magic = value( p );
+int i = value( p );
 pair( void *, int * ) q = { 0, &p.second };
-magic = value_p( q );
+i = value( q );
 double d = 1.0;
 pair( double *, double * ) r = { &d, &d };
-d = value_p( r );
+d = value( r );
 \end{cfa}
 
@@ -589,5 +600,5 @@
 [ double ] foo$\(_2\)$( int );
 void bar( int, double, double );
-bar( foo( 3 ), foo( 3 ) );
+`bar`( foo( 3 ), foo( 3 ) );
 \end{cfa}
 The type-resolver only has the tuple return-types to resolve the call to @bar@ as the @foo@ parameters are identical, which involves unifying the possible @foo@ functions with @bar@'s parameter list.
@@ -835,5 +846,5 @@
 Since @sum@\(_0\) does not accept any arguments, it is not a valid candidate function for the call @sum(10, 20, 30)@.
 In order to call @sum@\(_1\), @10@ is matched with @x@, and the argument resolution moves on to the argument pack @rest@, which consumes the remainder of the argument list and @Params@ is bound to @[20, 30]@.
-The process continues unitl @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion.
+The process continues until @Params@ is bound to @[]@, requiring an assertion @int sum()@, which matches @sum@\(_0\) and terminates the recursion.
 Effectively, this algorithm traces as @sum(10, 20, 30)@ $\rightarrow$ @10 + sum(20, 30)@ $\rightarrow$ @10 + (20 + sum(30))@ $\rightarrow$ @10 + (20 + (30 + sum()))@ $\rightarrow$ @10 + (20 + (30 + 0))@.
 
@@ -979,5 +990,158 @@
 \section{Control Structures}
 
-\CFA identifies missing and problematic control structures in C, and extends and modifies these control structures to increase functionality and safety.
+\CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds to control structures to increase functionality and safety.
+
+
+\subsection{\texorpdfstring{\LstKeywordStyle{if} Statement}{if Statement}}
+
+The @if@ expression allows declarations, similar to @for@ declaration expression:
+\begin{cfa}
+if ( int x = f() ) ...						$\C{// x != 0}$
+if ( int x = f(), y = g() ) ...				$\C{// x != 0 \&\& y != 0}$
+if ( int x = f(), y = g(); `x < y` ) ...	$\C{// relational expression}$
+\end{cfa}
+Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the @if@ expression, and the results are combined using the logical @&&@ operator.\footnote{\CC only provides a single declaration always compared not equal to 0.}
+The scope of the declaration(s) is local to the @if@ statement but exist within both the ``then'' and ``else'' clauses.
+
+
+\subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
+
+There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
+
+C has no shorthand for specifying a list of case values, whether the list is non-contiguous or contiguous\footnote{C provides this mechanism via fall through.}.
+\CFA provides a shorthand for a non-contiguous list:
+\begin{cquote}
+\lstDeleteShortInline@%
+\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+case 2, 10, 34, 42:
+\end{cfa}
+&
+\begin{cfa}
+case 2: case 10: case 34: case 42:
+\end{cfa}
+\end{tabular}
+\lstMakeShortInline@%
+\end{cquote}
+for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.}
+\begin{cquote}
+\lstDeleteShortInline@%
+\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+case 2~42:
+\end{cfa}
+&
+\begin{cfa}
+case 2: case 3: ... case 41: case 42:
+\end{cfa}
+\end{tabular}
+\lstMakeShortInline@%
+\end{cquote}
+and a combination:
+\begin{cfa}
+case -12~-4, -1~5, 14~21, 34~42:
+\end{cfa}
+
+C allows placement of @case@ clauses \emph{within} statements nested in the @switch@ body (see Duff's device~\cite{Duff83});
+\begin{cfa}
+switch ( i ) {
+  case 0:
+	for ( int i = 0; i < 10; i += 1 ) {
+		...
+  `case 1:`		// no initialization of loop index
+		...
+	}
+}
+\end{cfa}
+\CFA precludes this form of transfer into a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.
+
+C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:
+\begin{cfa}
+switch ( x ) {
+	`int y = 1;`							$\C{// unreachable initialization}$
+	`x = 7;`								$\C{// unreachable code without label/branch}$
+  case 0:
+	...
+	`int z = 0;`							$\C{// unreachable initialization, cannot appear after case}$
+	z = 2;
+  case 1:
+	`x = z;`								$\C{// without fall through, z is undefined}$
+}
+\end{cfa}
+\CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
+\CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
+
+C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through};
+@case@ clauses are made disjoint by the @break@ statement.
+While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
+For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through (see Figure~\ref{f:ChooseSwitchStatements}).
+Collectively, these enhancements reduce programmer burden and increase readability and safety.
+
+\begin{figure}
+\centering
+\lstDeleteShortInline@%
+\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+`choose` ( day ) {
+  case Mon~Thu:  // program
+
+  case Fri:  // program
+	wallet += pay;
+	`fallthrough;`
+  case Sat:  // party
+	wallet -= party;
+
+  case Sun:  // rest
+
+  default:  // error
+}
+\end{cfa}
+&
+\begin{cfa}
+switch ( day ) {
+  case Mon: case Tue: case Wed: case Thu:  // program
+	`break;`
+  case Fri:  // program
+	wallet += pay;
+
+  case Sat:  // party
+	wallet -= party;
+	`break;`
+  case Sun:  // rest
+	`break;`
+  default:  // error
+}
+\end{cfa}
+\end{tabular}
+\lstMakeShortInline@%
+\caption{\lstinline|choose| versus \lstinline|switch| Statements}
+\label{f:ChooseSwitchStatements}
+\end{figure}
+
+\begin{comment}
+Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter. 
+\CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases. 
+Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword. 
+Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below:
+
+\begin{cfa}
+choose( i ) {
+	case 2:
+		printf("even ");
+		fallthrough;
+	case 3: case 5: case 7:
+		printf("small prime\n");
+	case 4,6,8,9:
+		printf("small composite\n");
+	case 13~19:
+		printf("teen\n");
+	default:
+		printf("something else\n");
+}
+\end{cfa}
+\end{comment}
 
 
@@ -1039,5 +1203,5 @@
 		} else {
 			... goto `LIF`; ...
-		} `L3:` ;
+		} `LIF:` ;
 	} `LS:` ;
 } `LC:` ;
@@ -1089,139 +1253,123 @@
 
 
-\subsection{\texorpdfstring{Enhanced \LstKeywordStyle{switch} Statement}{Enhanced switch Statement}}
-
-There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
-
-C has no shorthand for specifying a list of case values, whether the list is non-contiguous or contiguous\footnote{C provides this mechanism via fall through.}.
-\CFA provides a shorthand for a non-contiguous list:
+\subsection{Exception Handling}
+
+The following framework for \CFA exception handling is in place, excluding a run-time type information and dynamic casts.
+\CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}).
+Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler.
+\CFA restricts exception types to those defined by aggregate type @exception@.
+The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@).
+If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
+If there is no current exception, the reresume/rethrow results in a runtime error.
+
+\begin{figure}
 \begin{cquote}
 \lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-case 2, 10, 34, 42:
-\end{cfa}
-&
-\begin{cfa}
-case 2: case 10: case 34: case 42:
+\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{Resumption}}	& \multicolumn{1}{c}{\textbf{Termination}}	\\
+\begin{cfa}
+`exception R { int fix; };`
+void f() {
+	R r;
+	... `resume( r );` ...
+	... r.fix // control does return here after handler
+}
+`try` {
+	... f(); ...
+} `catchResume( R r )` {
+	... r.fix = ...; // return correction to raise
+} // dynamic return to _Resume
+\end{cfa}
+&
+\begin{cfa}
+`exception T {};`
+void f() {
+
+	... `throw( T{} );` ...
+	// control does NOT return here after handler
+}
+`try` {
+	... f(); ...
+} `catch( T t )` {
+	... // recover and continue
+} // static return to next statement
 \end{cfa}
 \end{tabular}
 \lstMakeShortInline@%
 \end{cquote}
-for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.}
+\caption{\CFA Exception Handling}
+\label{f:CFAExceptionHandling}
+\end{figure}
+
+The set of exception types in a list of catch clause may include both a resumption and termination handler:
+\begin{cfa}
+try {
+	... resume( `R{}` ); ...
+} catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$
+   catch( `R` r ) { ... }					$\C{\color{red}// H2}$
+
+\end{cfa}
+The resumption propagation raises @R@ and the stack is not unwound;
+the exception is caught by the @catchResume@ clause and handler H1 is invoked.
+The termination propagation in handler H1 raises @R@ and the stack is unwound;
+the exception is caught by the @catch@ clause and handler H2 is invoked.
+The termination handler is available because the resumption propagation did not unwind the stack.
+
+An additional feature is conditional matching in a catch clause:
+\begin{cfa}
+try {
+	... write( `datafile`, ... ); ...		$\C{// may throw IOError}$
+	... write( `logfile`, ... ); ...
+} catch ( IOError err; `err.file == datafile` ) { ... } $\C{// handle datafile error}$
+   catch ( IOError err; `err.file == logfile` ) { ... } $\C{// handle logfile error}$
+   catch ( IOError err ) { ... }			$\C{// handler error from other files}$
+\end{cfa}
+where the throw inserts the failing file-handle in the I/O exception.
+Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible..
+
+The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
+\begin{cfa}
+resume( $\emph{exception-type}$, $\emph{alternate-stack}$ )
+resume( $\emph{alternate-stack}$ )
+\end{cfa}
+These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}.
+Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns.
+
+To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
+The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:
 \begin{cquote}
 \lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-case 2~42:
-\end{cfa}
-&
-\begin{cfa}
-case 2: case 3: ... case 41: case 42:
+\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
+\begin{cfa}
+enable $\emph{exception-type-list}$ {
+	// allow non-local resumption
+}
+\end{cfa}
+&
+\begin{cfa}
+disable $\emph{exception-type-list}$ {
+	// disallow non-local resumption
+}
 \end{cfa}
 \end{tabular}
 \lstMakeShortInline@%
 \end{cquote}
-and a combination:
-\begin{cfa}
-case -12~-4, -1~5, 14~21, 34~42:
-\end{cfa}
-
-C allows placement of @case@ clauses \emph{within} statements nested in the @switch@ body (see Duff's device~\cite{Duff83});
-\begin{cfa}
-switch ( i ) {
-  case 0:
-	for ( int i = 0; i < 10; i += 1 ) {
-		...
-  `case 1:`		// no initialization of loop index
-		...
-	}
-}
-\end{cfa}
-\CFA precludes this form of transfer into a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.
-
-C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:
-\begin{cfa}
-switch ( x ) {
-	`int y = 1;`				$\C{// unreachable initialization}$
-	`x = 7;`					$\C{// unreachable code without label/branch}$
-  case 0:
-	...
-	`int z = 0;`				$\C{// unreachable initialization, cannot appear after case}$
-	z = 2;
-  case 1:
-	`x = z;`					$\C{// without fall through, z is undefined}$
-}
-\end{cfa}
-\CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
-\CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
-
-C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through};
-@case@ clauses are made disjoint by the @break@ statement.
-While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
-For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through:
-\begin{cquote}
-\lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-`choose` ( day ) {
-  case Mon~Thu:  // program
-
-  case Fri:  // program
-	wallet += pay;
-	`fallthrough;`
-  case Sat:  // party
-	wallet -= party;
-
-  case Sun:  // rest
-
-  default:  // error
-}
-\end{cfa}
-&
-\begin{cfa}
-switch ( day ) {
-  case Mon: case Tue: case Wed: case Thu:  // program
-	`break;`
-  case Fri:  // program
-	wallet += pay;
-
-  case Sat:  // party
-	wallet -= party;
-	`break;`
-  case Sun:  // rest
-	`break;`
-  default:  // error
-}
-\end{cfa}
-\end{tabular}
-\lstMakeShortInline@%
-\end{cquote}
-Collectively, these enhancements reduce programmer burden and increase readability and safety.
-
-\begin{comment}
-Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter. 
-\CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases. 
-Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword. 
-Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below:
-
-\begin{cfa}
-choose( i ) {
-	case 2:
-		printf("even ");
-		fallthrough;
-	case 3: case 5: case 7:
-		printf("small prime\n");
-	case 4,6,8,9:
-		printf("small composite\n");
-	case 13~19:
-		printf("teen\n");
-	default:
-		printf("something else\n");
-}
-\end{cfa}
-\end{comment}
+The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
+Specifying no exception type is shorthand for specifying all exception types.
+Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state.
+
+Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
+\begin{cfa}
+try {
+	... f(); ...
+// catchResume or catch clauses
+} `finally` {
+	// house keeping
+}
+\end{cfa}
+The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
+If an exception is raised and caught, the handler is run before the finally clause.
+Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
+Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
 
 
@@ -1238,5 +1386,5 @@
 S s, as[10];
 \end{cfa}
-However, routines manipulating aggregates must repeat the aggregate name to access its containing fields:
+However, functions manipulating aggregates must repeat the aggregate name to access its containing fields:
 \begin{cfa}
 void f( S s ) {
@@ -1256,5 +1404,5 @@
 }
 \end{C++}
-Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
+Object-oriented nesting of member functions in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
 However, for other aggregate parameters, qualification is necessary:
 \begin{cfa}
@@ -1286,5 +1434,5 @@
 	'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$
 \end{cfa}
-and may appear as the body of a routine or nested within a routine body.
+and may appear as the body of a function or nested within a function body.
 Each expression in the expression-list provides a type and object.
 The type must be an aggregate type.
@@ -1313,5 +1461,5 @@
 Qualification or a cast is used to disambiguate.
 
-There is an interesting problem between parameters and the routine @with@, \eg:
+There is an interesting problem between parameters and the function @with@, \eg:
 \begin{cfa}
 void ?{}( S & s, int i ) with ( s ) {		$\C{// constructor}$
@@ -1319,5 +1467,5 @@
 }
 \end{cfa}
-Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the routine @with@.
+Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function @with@.
 To solve this problem, parameters are treated like an initialized aggregate:
 \begin{cfa}
@@ -1327,5 +1475,5 @@
 } params;
 \end{cfa}
-and implicitly opened \emph{after} a routine open, to give them higher priority:
+and implicitly opened \emph{after} a function open, to give them higher priority:
 \begin{cfa}
 void ?{}( S & s, int i ) with ( s ) `with( $\emph{\color{red}params}$ )` {
@@ -1355,125 +1503,4 @@
 
 
-\subsection{Exception Handling}
-
-The following framework for \CFA exception handling is in place, excluding a run-time type information and dynamic casts.
-\CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}).
-Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler.
-\CFA restricts exception types to those defined by aggregate type @exception@.
-The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@).
-If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
-If there is no current exception, the reresume/rethrow results in a runtime error.
-
-\begin{figure}
-\begin{cquote}
-\lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{Resumption}}	& \multicolumn{1}{c}{\textbf{Recovery}}	\\
-\begin{cfa}
-`exception R { int fix; };`
-void f() {
-	R r;
-	... `resume( r );` ...
-	... r.fix // control does return here after handler
-}
-`try` {
-	... f(); ...
-} `catchResume( R r )` {
-	... r.fix = ...; // return correction to raise
-} // dynamic return to _Resume
-\end{cfa}
-&
-\begin{cfa}
-`exception T {};`
-void f() {
-
-	... `throw( T{} );` ...
-	// control does NOT return here after handler
-}
-`try` {
-	... f(); ...
-} `catch( T t )` {
-	... // recover and continue
-} // static return to next statement
-\end{cfa}
-\end{tabular}
-\lstMakeShortInline@%
-\end{cquote}
-\caption{\CFA Exception Handling}
-\label{f:CFAExceptionHandling}
-\end{figure}
-
-The set of exception types in a list of catch clause may include both a resumption and termination handler:
-\begin{cfa}
-try {
-	... resume( `R{}` ); ...
-} catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$
-   catch( `R` r ) { ... }					$\C{\color{red}// H2}$
-
-\end{cfa}
-The resumption propagation raises @R@ and the stack is not unwound;
-the exception is caught by the @catchResume@ clause and handler H1 is invoked.
-The termination propagation in handler H1 raises @R@ and the stack is unwound;
-the exception is caught by the @catch@ clause and handler H2 is invoked.
-The termination handler is available because the resumption propagation did not unwind the stack.
-
-An additional feature is conditional matching in a catch clause:
-\begin{cfa}
-try {
-	... write( `datafile`, ... ); ...		$\C{// may throw IOError}$
-	... write( `logfile`, ... ); ...
-} catch ( IOError err; `err.file == datafile` ) { ... } $\C{// handle datafile error}$
-   catch ( IOError err; `err.file == logfile` ) { ... } $\C{// handle logfile error}$
-   catch ( IOError err ) { ... }			$\C{// handler error from other files}$
-\end{cfa}
-where the throw inserts the failing file-handle in the I/O exception.
-Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible..
-
-The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
-\begin{cfa}
-resume( $\emph{exception-type}$, $\emph{alternate-stack}$ )
-resume( $\emph{alternate-stack}$ )
-\end{cfa}
-These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}.
-Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns.
-
-To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
-The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:
-\begin{cquote}
-\lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
-\begin{cfa}
-enable $\emph{exception-type-list}$ {
-	// allow non-local resumption
-}
-\end{cfa}
-&
-\begin{cfa}
-disable $\emph{exception-type-list}$ {
-	// disallow non-local resumption
-}
-\end{cfa}
-\end{tabular}
-\lstMakeShortInline@%
-\end{cquote}
-The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
-Specifying no exception type is shorthand for specifying all exception types.
-Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state.
-
-Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
-\begin{cfa}
-try {
-	... f(); ...
-// catchResume or catch clauses
-} `finally` {
-	// house keeping
-}
-\end{cfa}
-The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
-If an exception is raised and caught, the handler is run before the finally clause.
-Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
-Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
-
-
 \section{Declarations}
 
@@ -1503,14 +1530,14 @@
 Is this an array of 5 pointers to integers or a pointer to an array of 5 integers?
 If there is any doubt, it implies productivity and safety issues even for basic programs.
-Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
-For example, a routine returning a pointer to an array of integers is defined and used in the following way:
+Another example of confusion results from the fact that a function name and its parameters are embedded within the return type, mimicking the way the return value is used at the function's call site.
+For example, a function returning a pointer to an array of integers is defined and used in the following way:
 \begin{cfa}
 int `(*`f`())[`5`]` {...};					$\C{// definition}$
  ... `(*`f`())[`3`]` += 1;					$\C{// usage}$
 \end{cfa}
-Essentially, the return type is wrapped around the routine name in successive layers (like an onion).
+Essentially, the return type is wrapped around the function name in successive layers (like an onion).
 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
 
-\CFA provides its own type, variable and routine declarations, using a different syntax.
+\CFA provides its own type, variable and function declarations, using a different syntax.
 The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right.
 The qualifiers have the same meaning but are ordered left to right to specify a variable's type.
@@ -1540,5 +1567,5 @@
 \end{cquote}
 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 routine parameter.
+% 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.
 For instance, variables @x@ and @y@ of type pointer to integer are defined in \CFA as follows:
@@ -1626,8 +1653,8 @@
 \lstMakeShortInline@%
 \end{cquote}
-Specifiers must appear at the start of a \CFA routine declaration\footnote{\label{StorageClassSpecifier}
+Specifiers must appear at the start of a \CFA function declaration\footnote{\label{StorageClassSpecifier}
 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}}.
 
-The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@:
+The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-function @sizeof@:
 \begin{cquote}
 \lstDeleteShortInline@%
@@ -1647,5 +1674,5 @@
 \end{cquote}
 
-The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
+The syntax of the new function-prototype declaration follows directly from the new function-definition syntax;
 as well, parameter names are optional, \eg:
 \begin{cfa}
@@ -1656,6 +1683,6 @@
 [ * int, int ] j ( int );					$\C{// returning pointer to int and int, with int parameter}$
 \end{cfa}
-This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
-Like C, it is possible to declare multiple routine-prototypes in a single declaration, where the return type is distributed across \emph{all} routine names in the declaration list, \eg:
+This syntax allows a prototype declaration to be created by cutting and pasting source text from the function-definition header (or vice versa).
+Like C, it is possible to declare multiple function-prototypes in a single declaration, where the return type is distributed across \emph{all} function names in the declaration list, \eg:
 \begin{cquote}
 \lstDeleteShortInline@%
@@ -1672,16 +1699,16 @@
 \lstMakeShortInline@%
 \end{cquote}
-where \CFA allows the last routine in the list to define its body.
-
-The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
-\begin{cfa}
-* [ int x ] () fp;							$\C{// pointer to routine returning int with no parameters}$
-* [ * int ] ( int y ) gp;					$\C{// pointer to routine returning pointer to int with int parameter}$
-* [ ] ( int, char ) hp;						$\C{// pointer to routine returning no result with int and char parameters}$
-* [ * int, int ] ( int ) jp;				$\C{// pointer to routine returning pointer to int and int, with int parameter}$
-\end{cfa}
-Note, a routine name cannot be specified:
-\begin{cfa}
-* [ int x ] f () fp;						$\C{// routine name "f" is disallowed}$
+where \CFA allows the last function in the list to define its body.
+
+The syntax for pointers to \CFA functions specifies the pointer name on the right, \eg:
+\begin{cfa}
+* [ int x ] () fp;							$\C{// pointer to function returning int with no parameters}$
+* [ * int ] ( int y ) gp;					$\C{// pointer to function returning pointer to int with int parameter}$
+* [ ] ( int, char ) hp;						$\C{// pointer to function returning no result with int and char parameters}$
+* [ * int, int ] ( int ) jp;				$\C{// pointer to function returning pointer to int and int, with int parameter}$
+\end{cfa}
+Note, a function name cannot be specified:
+\begin{cfa}
+* [ int x ] f () fp;						$\C{// function name "f" is disallowed}$
 \end{cfa}
 
@@ -1903,18 +1930,11 @@
 Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not deallocate.}.
 \begin{cfa}
-struct VLA {
-	int len, * data;
-};
-void ?{}( VLA & vla ) with ( vla ) {		$\C{// default constructor}$
-	len = 10;  data = alloc( len );			$\C{// shallow copy}$
-}
-void ^?{}( VLA & vla ) with ( vla ) {		$\C{// destructor}$
-	free( data );
-}
+struct VLA { int len, * data; };
+void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  $\C{// default constructor}$
+void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
 {
 	VLA x;									$\C{// implicit:  ?\{\}( x );}$
 } 											$\C{// implicit:  ?\^{}\{\}( x );}$
 \end{cfa}
-(Note, the example is purposely kept simple by using shallow-copy semantics.)
 @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. 
@@ -1924,11 +1944,12 @@
 \CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
 \begin{cfa}
-void ?{}( VLA & vla, int size, char fill ) with ( vla ) {	$\C{// initialization}$
+void ?{}( VLA & vla, int size, char fill ) with ( vla ) {  $\C{// initialization}$
 	len = size;  data = alloc( len, fill );
 }
-void ?{}( VLA & vla, VLA other ) {			$\C{// copy}$
+void ?{}( VLA & vla, VLA other ) {			$\C{// copy, shallow}$
 	vla.len = other.len;  vla.data = other.data;
 }
 \end{cfa}
+(Note, the example is purposely kept simple by using shallow-copy semantics.)
 An initialization constructor-call has the same syntax as a C initializer, except the initialization values are passed as arguments to a matching constructor (number and type of paremeters).
 \begin{cfa}
@@ -1944,6 +1965,6 @@
 \begin{cfa}
 {
-	VLA x,  y = { 20, 0x01 },  z = y;
-	// implicit:  ?{}( x );  ?{}( y, 20, 0x01 );  ?{}( z, y ); z points to y
+	VLA  x,            y = { 20, 0x01 },     z = y;	$\C{// z points to y}$
+	//      ?{}( x );  ?{}( y, 20, 0x01 );  ?{}( z, y ); 
 	^x{};									$\C{// deallocate x}$
 	x{};									$\C{// reallocate x}$
@@ -1952,5 +1973,5 @@
 	y{ x };									$\C{// reallocate y, points to x}$
 	x{};									$\C{// reallocate x, not pointing to y}$
-	// implicit:  ^?{}(z);  ^?{}(y);  ^?{}(x);
+	// ^?{}(z);  ^?{}(y);  ^?{}(x);
 }
 \end{cfa}
@@ -1983,5 +2004,39 @@
 C already includes limited polymorphism for literals -- @0@ can be either an integer or a pointer literal, depending on context, while the syntactic forms of literals of the various integer and float types are very similar, differing from each other only in suffix.
 In keeping with the general \CFA approach of adding features while respecting the ``C-style'' of doing things, C's polymorphic constants and typed literal syntax are extended to interoperate with user-defined types, while maintaining a backwards-compatible semantics.
-A trivial example is allowing the underscore to separate prefixes, digits, and suffixes in all \CFA constants, as in Ada, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@.
+A trivial example is allowing the underscore, as in Ada, to separate prefixes, digits, and suffixes in all \CFA constants, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@.
+
+
+\subsection{Integral Suffixes}
+
+Additional integral suffixes are added to cover all the integral types and lengths.
+\begin{cquote}
+\lstDeleteShortInline@%
+\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
+\begin{cfa}
+20`_hh`     // signed char
+21`_hhu`   // unsigned char
+22`_h`       // signed short int
+23`_uh`     // unsigned short int
+24`z`         // size_t
+\end{cfa}
+&
+\begin{cfa}
+20`_L8`      // int8_t
+21`_ul8`     // uint8_t
+22`_l16`     // int16_t
+23`_ul16`   // uint16_t
+24`_l32`     // int32_t
+\end{cfa}
+&
+\begin{cfa}
+25`_ul32`      // uint32_t
+26`_l64`        // int64_t
+27`_l64u`      // uint64_t
+26`_L128`     // int128
+27`_L128u`   // unsigned int128
+\end{cfa}
+\end{tabular}
+\lstMakeShortInline@%
+\end{cquote}
 
 
@@ -2000,62 +2055,84 @@
 
 
-\subsection{Integral Suffixes}
-
-Additional integral suffixes are added to cover all the integral types and lengths.
-\begin{cquote}
+\subsection{User Literals}
+
+For readability, it is useful to associate units to scale literals, \eg weight (stone, pound, kilogram) or time (seconds, minutes, hours).
+The left of Figure~\ref{f:UserLiteral} shows the \CFA alternative call-syntax (literal argument before function name), using the backquote, to convert basic literals into user literals.
+The backquote is a small character, making the unit (function name) predominate.
+For examples, the multi-precision integers in Section~\ref{s:MultiPrecisionIntegers} make use of user literals:
+{\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
+\begin{cfa}
+y = 9223372036854775807L|`mp| * 18446744073709551615UL|`mp|;
+y = "12345678901234567890123456789"|`mp| + "12345678901234567890123456789"|`mp|;
+\end{cfa}
+Because \CFA uses a standard function, all types and literals are applicable, as well as overloading and conversions.
+}%
+
+The right of Figure~\ref{f:UserLiteral} shows the equivalent \CC version using the underscore for the call-syntax.
+However, \CC restricts the types, \eg @unsigned long long int@ and @long double@ to represent integral and floating literals.
+After which, user literals must match (no conversions);
+hence, it is necessary to overload the unit with all appropriate types.
+Finally, the use of the single quote as a separator is restricted to digits, precluding its use in the literal prefix or suffix, and causes problems with most IDEs, which must be extended to deal with this alternate use of the single quote.
+
+\begin{figure}
+\centering
+\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
 \lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
-\begin{cfa}
-20_hh     // signed char
-21_hhu   // unsigned char
-22_h      // signed short int
-23_uh    // unsigned short int
-24z        // size_t
-\end{cfa}
-&
-\begin{cfa}
-20_L8     // int8_t
-21_ul8    // uint8_t
-22_l16    // int16_t
-23_ul16  // uint16_t
-24_l32    // int32_t
-\end{cfa}
-&
-\begin{cfa}
-25_ul32      // uint32_t
-26_l64        // int64_t
-27_l64u      // uint64_t
-26_L128     // int128
-27_L128u  // unsigned int128
+\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{\CC}}	\\
+\begin{cfa}
+struct W {
+	double stones;
+};
+void ?{}( W & w ) { w.stones = 0; }
+void ?{}( W & w, double w ) { w.stones = w; }
+W ?+?( W l, W r ) {
+	return (W){ l.stones + r.stones };
+}
+W |?`st|( double w ) { return (W){ w }; }
+W |?`lb|( double w ) { return (W){ w / 14.0 }; }
+W |?`kg|( double w ) { return (W) { w * 0.16 }; }
+
+
+
+int main() {
+	W w, heavy = { 20 };
+	w = 155|`lb|;
+	w = 0b_1111|`st|;
+	w = 0_233|`lb|;
+	w = 0x_9b_u|`kg|;
+	w = 5.5|`st| + 8|`kg| + 25.01|`lb| + heavy;
+}
+\end{cfa}
+&
+\begin{cfa}
+struct W {
+    double stones;
+    W() { stones = 0.0; }
+    W( double w ) { stones = w; }
+};
+W operator+( W l, W r ) {
+	return W( l.stones + r.stones );
+}
+W |operator"" _st|( unsigned long long int w ) { return W( w ); }
+W |operator"" _lb|( unsigned long long int w ) { return W( w / 14.0 ); }
+W |operator"" _kg|( unsigned long long int w ) { return W( w * 0.16 ); }
+W |operator"" _st|( long double w ) { return W( w ); }
+W |operator"" _lb|( long double w ) { return W( w / 14.0 ); }
+W |operator"" _kg|( long double w ) { return W( w * 0.16 ); }
+int main() {
+	W w, heavy = { 20 };
+	w = 155|_lb|;
+	w = 0b1111|_lb|;       // error, binary unsupported
+	w = 0${\color{red}'}$233|_lb|;          // quote separator
+	w = 0x9b|_kg|;
+	w = 5.5d|_st| + 8|_kg| + 25.01|_lb| + heavy;
+}
 \end{cfa}
 \end{tabular}
 \lstMakeShortInline@%
-\end{cquote}
-
-
-\subsection{Units}
-
-Alternative call syntax (literal argument before routine name) to convert basic literals into user literals.
-
-{\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
-\begin{cfa}
-struct Weight { double stones; };
-void ?{}( Weight & w ) { w.stones = 0; }	$\C{// operations}$
-void ?{}( Weight & w, double w ) { w.stones = w; }
-Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
-
-Weight |?`st|( double w ) { return (Weight){ w }; } $\C{// backquote for units}$
-Weight |?`lb|( double w ) { return (Weight){ w / 14.0 }; }
-Weight |?`kg|( double w ) { return (Weight) { w * 0.1575}; }
-
-int main() {
-	Weight w, heavy = { 20 };				$\C{// 20 stone}$
-	w = 155|`lb|;
-	w = 0x_9b_u|`lb|;						$\C{// hexadecimal unsigned weight (155)}$
-	w = 0_233|`lb|;							$\C{// octal weight (155)}$
-	w = 5|`st| + 8|`kg| + 25|`lb| + heavy;
-}
-\end{cfa}
-}%
+\caption{User Literal}
+\label{f:UserLiteral}
+\end{figure}
 
 
@@ -2067,5 +2144,5 @@
 In many cases, the interface is an inline wrapper providing overloading during compilation but zero cost at runtime.
 The following sections give a glimpse of the interface reduction to many C libraries.
-In many cases, @signed@/@unsigned@ @char@ and @short@ routines are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results.
+In many cases, @signed@/@unsigned@ @char@, @short@, and @_Complex@ functions are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results.
 
 
@@ -2095,18 +2172,19 @@
 \begin{cquote}
 \lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\lstset{basicstyle=\linespread{0.9}\sf\small}
+\begin{tabular}{@{}l@{\hspace{0.5\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{0.5\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
 \begin{cfa}
 MIN
 MAX
-M_PI
-M_E
-\end{cfa}
-&
-\begin{cfa}
-SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN,
-SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX,
-M_PI, M_PIl, M_CPI, M_CPIl,
-M_E, M_El, M_CE, M_CEl
+PI
+E
+\end{cfa}
+&
+\begin{cfa}
+SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN
+SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX
+M_PI, M_PIl
+M_E, M_El
 \end{cfa}
 \end{tabular}
@@ -2117,6 +2195,6 @@
 \subsection{Math}
 
-C library @math.h@ provides many mathematical routines.
-\CFA routine overloading is used to condense these mathematical routines, \eg:
+C library @math.h@ provides many mathematical functions.
+\CFA function overloading is used to condense these mathematical functions, \eg:
 \begin{cquote}
 \lstDeleteShortInline@%
@@ -2137,5 +2215,5 @@
 \lstMakeShortInline@%
 \end{cquote}
-The result is a significant reduction in names to access math routines, \eg:
+The result is a significant reduction in names to access math functions, \eg:
 \begin{cquote}
 \lstDeleteShortInline@%
@@ -2156,14 +2234,14 @@
 \lstMakeShortInline@%
 \end{cquote}
-While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a routine name with a single set of floating type(s).
+While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a function name with a single set of floating type(s).
 For example, it is impossible to overload @atan@ for both one and two arguments;
-instead the names @atan@ and @atan2@ are required.
-The key observation is that only a restricted set of type-generic macros are provided for a limited set of routine names, which do not generalize across the type system, as in \CFA.
+instead the names @atan@ and @atan2@ are required (see Section~\ref{s:NameOverloading}).
+The key observation is that only a restricted set of type-generic macros are provided for a limited set of function names, which do not generalize across the type system, as in \CFA.
 
 
 \subsection{Standard}
 
-C library @stdlib.h@ provides many general routines.
-\CFA routine overloading is used to condense these utility routines, \eg:
+C library @stdlib.h@ provides many general functions.
+\CFA function overloading is used to condense these utility functions, \eg:
 \begin{cquote}
 \lstDeleteShortInline@%
@@ -2184,5 +2262,5 @@
 \lstMakeShortInline@%
 \end{cquote}
-The result is a significant reduction in names to access utility routines, \eg:
+The result is a significant reduction in names to access utility functions, \eg:
 \begin{cquote}
 \lstDeleteShortInline@%
@@ -2203,5 +2281,5 @@
 \lstMakeShortInline@%
 \end{cquote}
-In additon, there are polymorphic routines, like @min@ and @max@, which work on any type with operators @?<?@ or @?>?@.
+In additon, there are polymorphic functions, like @min@ and @max@, which work on any type with operators @?<?@ or @?>?@.
 
 The following shows one example where \CFA \emph{extends} an existing standard C interface to reduce complexity and provide safety.
@@ -2220,59 +2298,7 @@
 An array may be filled, resized, or aligned.
 \end{description}
-Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation-routines and how all the capabilities can be combined into two \CFA routines.
-
-\CFA storage-management routines extend the C equivalents by overloading, providing shallow type-safety, and removing the need to specify the base allocation-size.
-The following example contrasts \CFA and C storage-allocation operation performing the same operations with the same type safety:
-\begin{cquote}
-\begin{cfa}[aboveskip=0pt]
-size_t  dim = 10;							$\C{// array dimension}$
-char fill = '\xff';							$\C{// initialization fill value}$
-int * ip;
-\end{cfa}
-\lstDeleteShortInline@%
-\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
-\begin{cfa}
-ip = alloc();
-ip = alloc( fill );
-ip = alloc( dim );
-ip = alloc( dim, fill );
-ip = alloc( ip, 2 * dim );
-ip = alloc( ip, 4 * dim, fill );
-
-ip = align_alloc( 16 );
-ip = align_alloc( 16, fill );
-ip = align_alloc( 16, dim );
-ip = align_alloc( 16, dim, fill );
-\end{cfa}
-&
-\begin{cfa}
-ip = (int *)malloc( sizeof( int ) );
-ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) );
-ip = (int *)malloc( dim * sizeof( int ) );
-ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
-ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
-ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
-
-ip = memalign( 16, sizeof( int ) );
-ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
-ip = memalign( 16, dim * sizeof( int ) );
-ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
-\end{cfa}
-\end{tabular}
-\lstMakeShortInline@%
-\end{cquote}
-Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization.
-Hence, there are @new@ and @anew@ routines for single and array variables, and the fill value is the arguments to the constructor, \eg:
-\begin{cfa}
-struct S { int i, j; };
-void ?{}( S & s, int i, int j ) { s.i = i; s.j = j; }
-S * s = new( 2, 3 );						$\C{// allocate storage and run constructor}$
-S * as = anew( dim, 2, 3 );					$\C{// each array element initialized to 2, 3}$
-\end{cfa}
-Note, \CC can only initialization array elements via the default constructor.
-
-Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.
-When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character.
+Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation-functions and how all the capabilities can be combined into two \CFA functions.
+\CFA storage-management functions extend the C equivalents by overloading, providing shallow type-safety, and removing the need to specify the base allocation-size.
+Figure~\ref{f:StorageAllocation} contrasts \CFA and C storage-allocation operation performing the same operations with the same type safety.
 
 \begin{table}
@@ -2300,4 +2326,62 @@
 \end{table}
 
+\begin{figure}
+\centering
+\begin{cquote}
+\begin{cfa}[aboveskip=0pt]
+size_t  dim = 10;							$\C{// array dimension}$
+char fill = '\xff';							$\C{// initialization fill value}$
+int * ip;
+\end{cfa}
+\lstDeleteShortInline@%
+\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
+\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{c}{\textbf{C}}	\\
+\begin{cfa}
+ip = alloc();
+ip = alloc( fill );
+ip = alloc( dim );
+ip = alloc( dim, fill );
+ip = alloc( ip, 2 * dim );
+ip = alloc( ip, 4 * dim, fill );
+
+ip = align_alloc( 16 );
+ip = align_alloc( 16, fill );
+ip = align_alloc( 16, dim );
+ip = align_alloc( 16, dim, fill );
+\end{cfa}
+&
+\begin{cfa}
+ip = (int *)malloc( sizeof( int ) );
+ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) );
+ip = (int *)malloc( dim * sizeof( int ) );
+ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
+ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
+ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
+
+ip = memalign( 16, sizeof( int ) );
+ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
+ip = memalign( 16, dim * sizeof( int ) );
+ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
+\end{cfa}
+\end{tabular}
+\lstMakeShortInline@%
+\end{cquote}
+\caption{\CFA versus C Storage-Allocation}
+\label{f:StorageAllocation}
+\end{figure}
+
+Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization.
+Hence, there are @new@ and @anew@ functions for single and array variables, and the fill value is the arguments to the constructor, \eg:
+\begin{cfa}
+struct S { int i, j; };
+void ?{}( S & s, int i, int j ) { s.i = i; s.j = j; }
+S * s = new( 2, 3 );						$\C{// allocate storage and run constructor}$
+S * as = anew( dim, 2, 3 );					$\C{// each array element initialized to 2, 3}$
+\end{cfa}
+Note, \CC can only initialization array elements via the default constructor.
+
+Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.
+When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character.
+
 
 \subsection{I/O}
@@ -2387,5 +2471,5 @@
 }%
 \end{itemize}
-There are routines to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.
+There are functions to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.
 
 
@@ -2394,5 +2478,5 @@
 
 \CFA has an interface to the GMP multi-precision signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
-The \CFA interface wraps GMP routines into operator routines to make programming with multi-precision integers identical to using fixed-sized integers.
+The \CFA interface wraps GMP functions into operator functions to make programming with multi-precision integers identical to using fixed-sized integers.
 The \CFA type name for multi-precision signed-integers is @Int@ and the header file is @gmp@.
 The following multi-precision factorial programs contrast using GMP with the \CFA and C interfaces.
@@ -2439,5 +2523,5 @@
 Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks would show little runtime variance, other than in length and clarity of source code.
 A more illustrative benchmark measures the costs of idiomatic usage of each language's features.
-Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ routine similar to that in Section~\ref{sec:variadic-tuples}.
+Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ function similar to that in Section~\ref{sec:variadic-tuples}.
 The benchmark test is similar for C and \CC.
 The experiment uses element types @int@ and @pair(_Bool, char)@, and pushes $N=40M$ elements on a generic stack, copies the stack, clears one of the stacks, finds the maximum value in the other stack, and prints $N/2$ (to reduce graph height) constants.
@@ -2446,25 +2530,22 @@
 \begin{cfa}[xleftmargin=3\parindentlnth,aboveskip=0pt,belowskip=0pt]
 int main( int argc, char * argv[] ) {
-	FILE * out = fopen( "cfa-out.txt", "w" );
-	int maxi = 0, vali = 42;
-	stack(int) si, ti;
-
-	REPEAT_TIMED( "push_int", N, push( &si, vali ); )
-	TIMED( "copy_int", ti = si; )
-	TIMED( "clear_int", clear( &si ); )
-	REPEAT_TIMED( "pop_int", N,
-		int xi = pop( &ti ); if ( xi > maxi ) { maxi = xi; } )
-	REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
-
-	pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)1, 'a' };
-	stack(pair(_Bool, char)) sp, tp;
-
-	REPEAT_TIMED( "push_pair", N, push( &sp, valp ); )
-	TIMED( "copy_pair", tp = sp; )
-	TIMED( "clear_pair", clear( &sp ); )
-	REPEAT_TIMED( "pop_pair", N,
-		pair(_Bool, char) xp = pop( &tp ); if ( xp > maxp ) { maxp = xp; } )
-	REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
-	fclose(out);
+	ofstream out = { "cfa-out.txt" };
+	int max = 0, val = 42;
+	stack( int ) s, t;
+
+	REPEAT_TIMED( "push_int", N, push( s, val ); )
+	TIMED( "copy_int", t = s; )
+	TIMED( "clear_int", clear( s ); )
+	REPEAT_TIMED( "pop_int", N, int v = pop( t ); max = max( v, max ); )
+	REPEAT_TIMED( "print_int", N/2, out | val | ':' | val | endl; )
+
+	pair( _Bool, char ) max = { false, '\0' }, val = { true, 'a' };
+	stack( pair( _Bool, char ) ) s, t;
+
+	REPEAT_TIMED( "push_pair", N, push( s, val ); )
+	TIMED( "copy_pair", t = s; )
+	TIMED( "clear_pair", clear( s ); )
+	REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) v = pop( t ); max = max( v, max ); )
+	REPEAT_TIMED( "print_pair", N/2, out | val | ':' | val | endl; )
 }
 \end{cfa}
@@ -2537,11 +2618,11 @@
 \CC is the most similar language to \CFA;
 both are extensions to C with source and runtime backwards compatibility.
-The fundamental difference is in their engineering approach to C compatibility and programmer expectation.
-While \CC provides good backwards compatibility with C, it has a steep learning curve for many of its extensions.
+The fundamental difference is the engineering approach to maintain C compatibility and programmer expectation.
+While \CC provides good compatibility with C, it has a steep learning curve for many of its extensions.
 For example, polymorphism is provided via three disjoint mechanisms: overloading, inheritance, and templates.
 The overloading is restricted because resolution does not use the return type, inheritance requires learning object-oriented programming and coping with a restricted nominal-inheritance hierarchy, templates cannot be separately compiled resulting in compilation/code bloat and poor error messages, and determining how these mechanisms interact and which to use is confusing.
 In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate-compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm.
-The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed properties for a type.
-Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function in code beyond compilation errors during template expansion;
+The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed type properties.
+Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function beyond compilation errors during template expansion;
 furthermore, \CC concepts are restricted to template polymorphism.
 
@@ -2594,4 +2675,7 @@
 
 
+\subsection{Control Structures / Declarations / Literals}
+
+
 \section{Conclusion and Future Work}
 
@@ -2620,5 +2704,6 @@
 
 The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, and Thierry Delisle on the features described in this paper, and thank Magnus Madsen for feedback in the writing.
-%This work is supported in part by a corporate partnership with \grantsponsor{Huawei}{Huawei Ltd.}{http://www.huawei.com}, and Aaron Moss and Peter Buhr are funded by the \grantsponsor{Natural Sciences and Engineering Research Council} of Canada.
+This work is supported through a corporate partnership with Huawei Ltd.\ (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr are funded by the Natural Sciences and Engineering Research Council of Canada.
+
 % the first author's \grantsponsor{NSERC-PGS}{NSERC PGS D}{http://www.nserc-crsng.gc.ca/Students-Etudiants/PG-CS/BellandPostgrad-BelletSuperieures_eng.asp} scholarship.
 
@@ -2640,13 +2725,19 @@
 \CFA
 \begin{cfa}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
+forall(otype T) struct stack_node;
+forall(otype T) struct stack {
+	stack_node(T) * head;
+};
 forall(otype T) struct stack_node {
 	T value;
 	stack_node(T) * next;
 };
-forall(otype T) void ?{}(stack(T) * s) { (&s->head){ 0 }; }
-forall(otype T) void ?{}(stack(T) * s, stack(T) t) {
-	stack_node(T) ** crnt = &s->head;
+forall(otype T) void ?{}( stack(T) & s ) { (s.head){ 0 }; }
+forall(otype T) void ?{}( stack(T) & s, stack(T) t ) {
+	stack_node(T) ** crnt = &s.head;
 	for ( stack_node(T) * next = t.head; next; next = next->next ) {
-		*crnt = ((stack_node(T) *)malloc()){ next->value }; /***/
+		stack_node(T) * new_node = ((stack_node(T)*)malloc());
+		(*new_node){ next->value }; /***/
+		*crnt = new_node;
 		stack_node(T) * acrnt = *crnt;
 		crnt = &acrnt->next;
@@ -2654,30 +2745,31 @@
 	*crnt = 0;
 }
-forall(otype T) stack(T) ?=?(stack(T) * s, stack(T) t) {
-	if ( s->head == t.head ) return *s;
-	clear(s);
+forall(otype T) stack(T) ?=?( stack(T) & s, stack(T) t ) {
+	if ( s.head == t.head ) return s;
+	clear( s );
 	s{ t };
-	return *s;
-}
-forall(otype T) void ^?{}(stack(T) * s) { clear(s); }
-forall(otype T) _Bool empty(const stack(T) * s) { return s->head == 0; }
-forall(otype T) void push(stack(T) * s, T value) {
-	s->head = ((stack_node(T) *)malloc()){ value, s->head }; /***/
-}
-forall(otype T) T pop(stack(T) * s) {
-	stack_node(T) * n = s->head;
-	s->head = n->next;
-	T x = n->value;
-	^n{};
-	free(n);
-	return x;
-}
-forall(otype T) void clear(stack(T) * s) {
-	for ( stack_node(T) * next = s->head; next; ) {
+	return s;
+}
+forall(otype T) void ^?{}( stack(T) & s) { clear( s ); }
+forall(otype T) _Bool empty( const stack(T) & s ) { return s.head == 0; }
+forall(otype T) void push( stack(T) & s, T value ) {
+	stack_node(T) * new_node = ((stack_node(T)*)malloc());
+	(*new_node){ value, s.head }; /***/
+	s.head = new_node;
+}
+forall(otype T) T pop( stack(T) & s ) {
+	stack_node(T) * n = s.head;
+	s.head = n->next;
+	T v = n->value;
+	delete( n );
+	return v;
+}
+forall(otype T) void clear( stack(T) & s ) {
+	for ( stack_node(T) * next = s.head; next; ) {
 		stack_node(T) * crnt = next;
 		next = crnt->next;
-		delete(crnt);
+		delete( crnt );
 	}
-	s->head = 0;
+	s.head = 0;
 }
 \end{cfa}
@@ -2827,100 +2919,4 @@
 
 
-\begin{comment}
-
-\subsubsection{bench.h}
-(\texttt{bench.hpp} is similar.)
-
-\lstinputlisting{evaluation/bench.h}
-
-\subsection{C}
-
-\subsubsection{c-stack.h} ~
-
-\lstinputlisting{evaluation/c-stack.h}
-
-\subsubsection{c-stack.c} ~
-
-\lstinputlisting{evaluation/c-stack.c}
-
-\subsubsection{c-pair.h} ~
-
-\lstinputlisting{evaluation/c-pair.h}
-
-\subsubsection{c-pair.c} ~
-
-\lstinputlisting{evaluation/c-pair.c}
-
-\subsubsection{c-print.h} ~
-
-\lstinputlisting{evaluation/c-print.h}
-
-\subsubsection{c-print.c} ~
-
-\lstinputlisting{evaluation/c-print.c}
-
-\subsubsection{c-bench.c} ~
-
-\lstinputlisting{evaluation/c-bench.c}
-
-\subsection{\CFA}
-
-\subsubsection{cfa-stack.h} ~
-
-\lstinputlisting{evaluation/cfa-stack.h}
-
-\subsubsection{cfa-stack.c} ~
-
-\lstinputlisting{evaluation/cfa-stack.c}
-
-\subsubsection{cfa-print.h} ~
-
-\lstinputlisting{evaluation/cfa-print.h}
-
-\subsubsection{cfa-print.c} ~
-
-\lstinputlisting{evaluation/cfa-print.c}
-
-\subsubsection{cfa-bench.c} ~
-
-\lstinputlisting{evaluation/cfa-bench.c}
-
-\subsection{\CC}
-
-\subsubsection{cpp-stack.hpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-stack.hpp}
-
-\subsubsection{cpp-print.hpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-print.hpp}
-
-\subsubsection{cpp-bench.cpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-bench.cpp}
-
-\subsection{\CCV}
-
-\subsubsection{object.hpp} ~
-
-\lstinputlisting[language=c++]{evaluation/object.hpp}
-
-\subsubsection{cpp-vstack.hpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-vstack.hpp}
-
-\subsubsection{cpp-vstack.cpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-vstack.cpp}
-
-\subsubsection{cpp-vprint.hpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-vprint.hpp}
-
-\subsubsection{cpp-vbench.cpp} ~
-
-\lstinputlisting[language=c++]{evaluation/cpp-vbench.cpp}
-\end{comment}
-
 \end{document}
 
Index: doc/papers/general/evaluation/cfa-bench.c
===================================================================
--- doc/papers/general/evaluation/cfa-bench.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/papers/general/evaluation/cfa-bench.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -1,3 +1,5 @@
-#include <stdio.h>
+#include <fstream>
+#include <stdlib>
+#include <stdbool.h>
 #include "bench.h"
 #include "cfa-stack.h"
@@ -5,27 +7,22 @@
 #include "cfa-print.h"
 
-int main( int argc, char *argv[] ) {
-	FILE * out = fopen( "/dev/null", "w" );
-	int maxi = 0, vali = 42;
-	stack(int) si, ti;
+int main( int argc, char * argv[] ) {
+	ofstream out = { "/dev/null" };
+	int max = 0, val = 42;
+	stack( int ) s, t;
 
-	REPEAT_TIMED( "push_int", N, push( &si, vali ); )
-	TIMED( "copy_int", ti = si; )
-	TIMED( "clear_int", clear( &si ); )
-	REPEAT_TIMED( "pop_int", N, 
-		int xi = pop( &ti ); 
-		if ( xi > maxi ) { maxi = xi; } )
-	REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
+	REPEAT_TIMED( "push_int", N, push( s, val ); )
+	TIMED( "copy_int", t = s; )
+	TIMED( "clear_int", clear( s ); )
+	REPEAT_TIMED( "pop_int", N, int x = pop( t ); max = max( x, max ); )
+	REPEAT_TIMED( "print_int", N/2, out | val | ':' | val | endl; )
 
-	pair(_Bool, char) maxp = { (_Bool)0, '\0' }, valp = { (_Bool)1, 'a' };
-	stack(pair(_Bool, char)) sp, tp;
+	pair( _Bool, char ) max = { (_Bool)false, '\0' }, val = { (_Bool)true, 'a' };
+	stack( pair( _Bool, char ) ) s, t;
 
-	REPEAT_TIMED( "push_pair", N, push( &sp, valp ); )
-	TIMED( "copy_pair", tp = sp; )
-	TIMED( "clear_pair", clear( &sp ); )
-	REPEAT_TIMED( "pop_pair", N, 
-		pair(_Bool, char) xp = pop( &tp ); 
-		if ( xp > maxp ) { maxp = xp; } )
-	REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
-	fclose(out);
+	REPEAT_TIMED( "push_pair", N, push( s, val ); )
+	TIMED( "copy_pair", t = s; )
+	TIMED( "clear_pair", clear( s ); )
+	REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) x = pop( t ); max = max( x, max ); )
+	REPEAT_TIMED( "print_pair", N/2, out | val | ':' | val | endl; )
 }
Index: doc/papers/general/evaluation/cfa-pair.c
===================================================================
--- doc/papers/general/evaluation/cfa-pair.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/papers/general/evaluation/cfa-pair.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -1,5 +1,6 @@
 #include "cfa-pair.h"
+#include "fstream"
 
-forall(otype R, otype S 
+forall(otype R, otype S
 	| { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); })
 int ?<?(pair(R, S) p, pair(R, S) q) {
@@ -7,5 +8,5 @@
 }
 
-forall(otype R, otype S 
+forall(otype R, otype S
 	| { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); })
 int ?<=?(pair(R, S) p, pair(R, S) q) {
@@ -23,5 +24,5 @@
 }
 
-forall(otype R, otype S 
+forall(otype R, otype S
 	| { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); })
 int ?>?(pair(R, S) p, pair(R, S) q) {
@@ -29,7 +30,13 @@
 }
 
-forall(otype R, otype S 
+forall(otype R, otype S
 	| { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
 int ?>=?(pair(R, S) p, pair(R, S) q) {
 	return p.first > q.first || ( p.first == q.first && p.second >= q.second );
 }
+
+forall(otype R, otype S)
+forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, R ); ostype & ?|?( ostype &, S );  })
+ostype & ?|?( ostype & os, pair(R, S) p ) {
+	return os | '[' | p.first | ',' | p.second | ']';
+} // ?|?
Index: doc/papers/general/evaluation/cfa-pair.h
===================================================================
--- doc/papers/general/evaluation/cfa-pair.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/papers/general/evaluation/cfa-pair.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -1,3 +1,5 @@
 #pragma once
+
+#include "iostream"
 
 forall(otype R, otype S) struct pair {
@@ -27,2 +29,6 @@
 	| { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
 int ?>=?(pair(R, S) p, pair(R, S) q);
+
+forall(otype R, otype S)
+forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, pair(R, S) ); })
+ostype & ?|?( ostype & os, pair(R, S) );
Index: doc/papers/general/evaluation/cfa-stack.c
===================================================================
--- doc/papers/general/evaluation/cfa-stack.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/papers/general/evaluation/cfa-stack.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -4,14 +4,21 @@
 forall(otype T) struct stack_node {
 	T value;
-	stack_node(T)* next;
+	stack_node(T) * next;
 };
+forall(otype T) void ?{}( stack_node(T) & node, T value, stack_node(T) * next ) {
+    node.value = value;
+    node.next = next;
+}
 
-forall(otype T) void ?{}(stack(T)* s) { (&s->head){ 0 }; }
+forall(otype T) void ?{}( stack(T) & s ) { (s.head){ 0 }; }
 
-forall(otype T) void ?{}(stack(T)* s, stack(T) t) {
-	stack_node(T)** crnt = &s->head;
-	for ( stack_node(T)* next = t.head; next; next = next->next ) {
-		*crnt = ((stack_node(T)*)malloc()){ next->value }; /***/
-		stack_node(T)* acrnt = *crnt;
+forall(otype T) void ?{}( stack(T) & s, stack(T) t ) {
+	stack_node(T) ** crnt = &s.head;
+	for ( stack_node(T) * next = t.head; next; next = next->next ) {
+		// *crnt = new( next->value, 0 );
+		stack_node(T)* new_node = ((stack_node(T)*)malloc());
+		(*new_node){ next->value }; /***/
+		*crnt = new_node;
+		stack_node(T) * acrnt = *crnt;
 		crnt = &acrnt->next;
 	}
@@ -19,34 +26,36 @@
 }
 
-forall(otype T) stack(T) ?=?(stack(T)* s, stack(T) t) {
-	if ( s->head == t.head ) return *s;
-	clear(s);
+forall(otype T) stack(T) ?=?( stack(T) & s, stack(T) t ) {
+	if ( s.head == t.head ) return s;
+	clear( s );
 	s{ t };
-	return *s;
+	return s;
 }
 
-forall(otype T) void ^?{}(stack(T)* s) { clear(s); }
+forall(otype T) void ^?{}( stack(T) & s) { clear( s ); }
 
-forall(otype T) _Bool empty(const stack(T)* s) { return s->head == 0; }
+forall(otype T) _Bool empty( const stack(T) & s ) { return s.head == 0; }
 
-forall(otype T) void push(stack(T)* s, T value) {
-	s->head = ((stack_node(T)*)malloc()){ value, s->head }; /***/
+forall(otype T) void push( stack(T) & s, T value ) {
+	// s.head = new( value, s.head );
+	stack_node(T)* new_node = ((stack_node(T)*)malloc());
+	(*new_node){ value, s.head }; /***/
+	s.head = new_node;
 }
 
-forall(otype T) T pop(stack(T)* s) {
-	stack_node(T)* n = s->head;
-	s->head = n->next;
-	T x = n->value;
-	^n{};
-	free(n);
-	return x;
+forall(otype T) T pop( stack(T) & s ) {
+	stack_node(T) * n = s.head;
+	s.head = n->next;
+	T v = n->value;
+	delete( n );
+	return v;
 }
 
-forall(otype T) void clear(stack(T)* s) {
-    for ( stack_node(T)* next = s->head; next; ) {
-		stack_node(T)* crnt = next;
+forall(otype T) void clear( stack(T) & s ) {
+	for ( stack_node(T) * next = s.head; next; ) {
+		stack_node(T) * crnt = next;
 		next = crnt->next;
-		delete(crnt);
+		delete( crnt );
 	}
-	s->head = 0;
+	s.head = 0;
 }
Index: doc/papers/general/evaluation/cfa-stack.h
===================================================================
--- doc/papers/general/evaluation/cfa-stack.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ doc/papers/general/evaluation/cfa-stack.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -3,14 +3,14 @@
 forall(otype T) struct stack_node;
 forall(otype T) struct stack {
-	stack_node(T)* head;
+	stack_node(T) * head;
 };
 
-forall(otype T) void ?{}(stack(T)* s);
-forall(otype T) void ?{}(stack(T)* s, stack(T) t);
-forall(otype T) stack(T) ?=?(stack(T)* s, stack(T) t);
-forall(otype T) void ^?{}(stack(T)* s);
+forall(otype T) void ?{}( stack(T) & s );
+forall(otype T) void ?{}( stack(T) & s, stack(T) t );
+forall(otype T) stack(T) ?=?( stack(T) & s, stack(T) t );
+forall(otype T) void ^?{}( stack(T) & s);
 
-forall(otype T) _Bool empty(const stack(T)* s);
-forall(otype T) void push(stack(T)* s, T value);
-forall(otype T) T pop(stack(T)* s);
-forall(otype T) void clear(stack(T)* s);
+forall(otype T) _Bool empty( const stack(T) & s );
+forall(otype T) void push( stack(T) & s, T value );
+forall(otype T) T pop( stack(T) & s );
+forall(otype T) void clear( stack(T) & s );
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/PassVisitor.impl.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -2277,40 +2277,149 @@
 }
 
-
+//--------------------------------------------------------------------------
+// TupleType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TupleType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->types, *this );
+	maybeAccept_impl( node->members, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+	maybeMutate_impl( node->types, *this );
+	maybeMutate_impl( node->members, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// TypeofType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TypeofType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	assert( node->expr );
+	maybeAccept_impl( node->expr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
+	MUTATE_START( node );
+
+	assert( node->expr );
+	maybeMutate_impl( node->expr, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// AttrType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( AttrType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	if ( node->isType ) {
+		assert( node->type );
+		maybeAccept_impl( node->type, *this );
+	} else {
+		assert( node->expr );
+		maybeAccept_impl( node->expr, *this );
+	} // if
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
+	MUTATE_START( node );
+
+	if ( node->isType ) {
+		assert( node->type );
+		maybeMutate_impl( node->type, *this );
+	} else {
+		assert( node->expr );
+		maybeMutate_impl( node->expr, *this );
+	} // if
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// VarArgsType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( VarArgsType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// ZeroType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ZeroType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// OneType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( OneType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( OneType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// Designation
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Designation * node ) {
 	VISIT_START( node );
 
-	maybeAccept_impl( node->get_designators(), *this );
+	maybeAccept_impl( node->designators, *this );
 
 	VISIT_END( node );
@@ -2321,5 +2430,5 @@
 	MUTATE_START( node );
 
-	maybeMutate_impl( node->get_designators(), *this );
+	maybeMutate_impl( node->designators, *this );
 
 	MUTATE_END( Designation, node );
@@ -2332,5 +2441,5 @@
 	VISIT_START( node );
 
-	visitExpression( node->get_value() );
+	visitExpression( node->value );
 
 	VISIT_END( node );
@@ -2341,91 +2450,109 @@
 	MUTATE_START( node );
 
-	node->set_value( mutateExpression( node->get_value() ) );
+	node->value = mutateExpression( node->value );
 
 	MUTATE_END( Initializer, node );
 }
 
+//--------------------------------------------------------------------------
+// ListInit
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ListInit * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->designations, *this );
+	maybeAccept_impl( node->initializers, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->designations, *this );
+	maybeMutate_impl( node->initializers, *this );
+
+	MUTATE_END( Initializer, node );
+}
+
+//--------------------------------------------------------------------------
+// ConstructorInit
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->ctor, *this );
+	maybeAccept_impl( node->dtor, *this );
+	maybeAccept_impl( node->init, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->ctor, *this );
+	maybeMutate_impl( node->dtor, *this );
+	maybeMutate_impl( node->init, *this );
+
+	MUTATE_END( Initializer, node );
+}
+
+//--------------------------------------------------------------------------
+// Subrange
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Subrange * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
+	MUTATE_START( node );
+
+	MUTATE_END( Subrange, node );
+}
+
+//--------------------------------------------------------------------------
+// Attribute
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Constant * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
+	MUTATE_START( node );
+
+	MUTATE_END( Constant, node );
+}
+
+//--------------------------------------------------------------------------
+// Attribute
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Attribute * node ) {
-	VISIT_BODY( node );
-}
-
-//---------------------------------------------------------------------------------------------------------------
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( OneType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
-	MUTATE_BODY( Initializer, node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
-	MUTATE_BODY( Initializer, node );
-}
-
-template< typename pass_type >
-Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
-	MUTATE_BODY( Subrange, node );
-}
-
-template< typename pass_type >
-Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
-	MUTATE_BODY( Constant, node );
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
 }
 
 template< typename pass_type >
 Attribute * PassVisitor< pass_type >::mutate( Attribute * node  )  {
-	MUTATE_BODY( Attribute, node );
-}
-
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->parameters, *this );
+
+	MUTATE_END( Attribute, node );
+}
+
+//--------------------------------------------------------------------------
+// TypeSubstitution
 template< typename pass_type >
 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/SemanticError.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -14,4 +14,5 @@
 //
 
+#include <cstdarg>
 #include <cstdio>										// for fileno, stderr
 #include <unistd.h>										// for isatty
@@ -50,5 +51,26 @@
 }
 
-void SemanticWarningImpl( CodeLocation location, std::string msg ) {
+namespace {
+	// convert format string and arguments into a single string
+	std::string fmtToString(const char * fmt, va_list ap) {
+		int size = 128;
+		while ( true ) {
+			char buf[size];
+			va_list args;
+			va_copy( args, ap );
+			int n = vsnprintf(&buf[0], size, fmt, args);
+			va_end( args );
+			if ( n < size && n >= 0 ) return buf;
+			size *= 2;
+		}
+		assert( false );
+	}
+}
+
+void SemanticWarningImpl( CodeLocation location, Warning, const char * const fmt, ... ) {
+	va_list args;
+	va_start(args, fmt);
+	std::string msg = fmtToString( fmt, args );
+	va_end(args);
 	std::cerr << ErrorHelpers::bold() << location << ErrorHelpers::warning_str() << ErrorHelpers::reset_font() << msg << std::endl;
 }
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/SemanticError.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -37,8 +37,9 @@
 
 constexpr const char * const WarningFormats[] = {
-
+	"self assignment of expression: %s",
 };
 
 enum class Warning {
+	SelfAssignment,
 	NUMBER_OF_WARNINGS, //This MUST be the last warning
 };
@@ -49,5 +50,5 @@
 );
 
-#define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[id], __VA_ARGS__)
+#define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[(int)id], __VA_ARGS__)
 
 void SemanticWarningImpl (CodeLocation loc, Warning warn, const char * const fmt, ...) __attribute__((format(printf, 3, 4)));
@@ -71,7 +72,4 @@
 }
 
-
-
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/utility.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -162,4 +162,6 @@
 }
 
+#define toCString( ... ) toString( __VA_ARGS__ ).c_str()
+
 // replace element of list with all elements of another list
 template< typename T >
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/GenPoly/Specialize.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -200,26 +200,4 @@
 	}
 
-	struct EnvTrimmer {
-		TypeSubstitution * env, * newEnv;
-		EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
-		void previsit( TypeDecl * tyDecl ) {
-			// transfer known bindings for seen type variables
-			if ( Type * t = env->lookup( tyDecl->name ) ) {
-				newEnv->add( tyDecl->name, t );
-			}
-		}
-	};
-
-	/// reduce environment to just the parts that are referenced in a given expression
-	TypeSubstitution * trimEnv( ApplicationExpr * expr, TypeSubstitution * env ) {
-		if ( env ) {
-			TypeSubstitution * newEnv = new TypeSubstitution();
-			PassVisitor<EnvTrimmer> trimmer( env, newEnv );
-			expr->accept( trimmer );
-			return newEnv;
-		}
-		return nullptr;
-	}
-
 	/// Generates a thunk that calls `actual` with type `funType` and returns its address
 	Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
@@ -265,5 +243,5 @@
 		}
 
-		appExpr->set_env( trimEnv( appExpr, env ) );
+		appExpr->env = TypeSubstitution::newFromExpr( appExpr, env );
 		if ( inferParams ) {
 			appExpr->get_inferParams() = *inferParams;
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/InitTweak/FixInit.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -68,4 +68,8 @@
 		typedef std::unordered_map< int, int > UnqCount;
 
+		struct SelfAssignChecker {
+			void previsit( ApplicationExpr * appExpr );
+		};
+
 		struct InsertImplicitCalls : public WithTypeSubstitution {
 			/// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
@@ -183,5 +187,5 @@
 		};
 
-		class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
+		class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithTypeSubstitution {
 		  public:
 			FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
@@ -235,4 +239,7 @@
 
 	void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
+		PassVisitor<SelfAssignChecker> checker;
+		acceptAll( translationUnit, checker );
+
 		// fixes ConstructorInit for global variables. should happen before fixInitializers.
 		InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
@@ -311,4 +318,81 @@
 		}
 
+		namespace {
+			// Relatively simple structural comparison for expressions, needed to determine
+			// if two expressions are "the same" (used to determine if self assignment occurs)
+			struct StructuralChecker {
+				Expression * stripCasts( Expression * expr ) {
+					// this might be too permissive. It's possible that only particular casts are relevant.
+					while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {
+						expr = cast->arg;
+					}
+					return expr;
+				}
+
+				void previsit( Expression * ) {
+					// anything else does not qualify
+					isSimilar = false;
+				}
+
+				template<typename T>
+				T * cast( Expression * node ) {
+					// all expressions need to ignore casts, so this bit has been factored out
+					return dynamic_cast< T * >( stripCasts( node ) );
+				}
+
+				// ignore casts
+				void previsit( CastExpr * ) {}
+
+				void previsit( MemberExpr * memExpr ) {
+					if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {
+						if ( otherMember->member == memExpr->member ) {
+							other = otherMember->aggregate;
+							return;
+						}
+					}
+					isSimilar = false;
+				}
+
+				void previsit( VariableExpr * varExpr ) {
+					if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {
+						if ( otherVar->var == varExpr->var ) {
+							return;
+						}
+					}
+					isSimilar = false;
+				}
+
+				void previsit( AddressExpr * ) {
+					if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {
+						other = addrExpr->arg;
+						return;
+					}
+					isSimilar = false;
+				}
+
+				Expression * other = nullptr;
+				bool isSimilar = true;
+			};
+
+			bool structurallySimilar( Expression * e1, Expression * e2 ) {
+				PassVisitor<StructuralChecker> checker;
+				checker.pass.other = e2;
+				e1->accept( checker );
+				return checker.pass.isSimilar;
+			}
+		}
+
+		void SelfAssignChecker::previsit( ApplicationExpr * appExpr ) {
+			DeclarationWithType * function = getFunction( appExpr );
+			if ( isAssignment( function ) ) {
+				if ( appExpr->args.size() == 2 ) {
+					// check for structural similarity (same variable use, ignore casts, etc. - but does not look too deeply, anything looking like a function is off limits)
+					if ( structurallySimilar( appExpr->args.front(), appExpr->args.back() ) ) {
+						SemanticWarning( appExpr->location, Warning::SelfAssignment, toCString( appExpr->args.front() ) );
+					}
+				}
+			}
+		}
+
 		Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
 			if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
@@ -364,9 +448,9 @@
 			ResolvExpr::findVoidExpression( resolved, indexer );
 			assert( resolved );
-			if ( resolved->get_env() ) {
+			if ( resolved->env ) {
 				// Extract useful information and discard new environments. Keeping them causes problems in PolyMutator passes.
-				env->add( *resolved->get_env() );
-				delete resolved->get_env();
-				resolved->set_env( nullptr );
+				env->add( *resolved->env );
+				delete resolved->env;
+				resolved->env = nullptr;
 			} // if
 			delete stmt;
@@ -550,4 +634,7 @@
 			// add destructors after current statement
 			for ( Expression * dtor : dtors ) {
+				// take relevant bindings from environment
+				assert( ! dtor->env );
+				dtor->env =  maybeClone( env );
 				stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
 			} // for
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Makefile.in	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -247,6 +247,4 @@
 	SynTree/driver_cfa_cpp-TypeDecl.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Initializer.$(OBJEXT) \
-	SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \
-	SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
@@ -527,9 +525,8 @@
 	SynTree/FunctionDecl.cc SynTree/AggregateDecl.cc \
 	SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
-	SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
-	SynTree/TypeSubstitution.cc SynTree/Attribute.cc \
-	SynTree/VarExprReplacer.cc Tuples/TupleAssignment.cc \
-	Tuples/TupleExpansion.cc Tuples/Explode.cc \
-	Virtual/ExpandCasts.cc
+	SynTree/Initializer.cc SynTree/TypeSubstitution.cc \
+	SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
+	Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
+	Tuples/Explode.cc Virtual/ExpandCasts.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -911,8 +908,4 @@
 SynTree/driver_cfa_cpp-Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
 	SynTree/$(DEPDIR)/$(am__dirstamp)
-SynTree/driver_cfa_cpp-Visitor.$(OBJEXT): SynTree/$(am__dirstamp) \
-	SynTree/$(DEPDIR)/$(am__dirstamp)
-SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \
-	SynTree/$(DEPDIR)/$(am__dirstamp)
 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
 	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
@@ -1053,5 +1046,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po@am__quote@
@@ -1069,5 +1061,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@
@@ -2478,32 +2469,4 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Initializer.obj `if test -f 'SynTree/Initializer.cc'; then $(CYGPATH_W) 'SynTree/Initializer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Initializer.cc'; fi`
-
-SynTree/driver_cfa_cpp-Visitor.o: SynTree/Visitor.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Visitor.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo -c -o SynTree/driver_cfa_cpp-Visitor.o `test -f 'SynTree/Visitor.cc' || echo '$(srcdir)/'`SynTree/Visitor.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Visitor.cc' object='SynTree/driver_cfa_cpp-Visitor.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Visitor.o `test -f 'SynTree/Visitor.cc' || echo '$(srcdir)/'`SynTree/Visitor.cc
-
-SynTree/driver_cfa_cpp-Visitor.obj: SynTree/Visitor.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Visitor.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo -c -o SynTree/driver_cfa_cpp-Visitor.obj `if test -f 'SynTree/Visitor.cc'; then $(CYGPATH_W) 'SynTree/Visitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Visitor.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Visitor.cc' object='SynTree/driver_cfa_cpp-Visitor.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Visitor.obj `if test -f 'SynTree/Visitor.cc'; then $(CYGPATH_W) 'SynTree/Visitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Visitor.cc'; fi`
-
-SynTree/driver_cfa_cpp-Mutator.o: SynTree/Mutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Mutator.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo -c -o SynTree/driver_cfa_cpp-Mutator.o `test -f 'SynTree/Mutator.cc' || echo '$(srcdir)/'`SynTree/Mutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Mutator.cc' object='SynTree/driver_cfa_cpp-Mutator.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.o `test -f 'SynTree/Mutator.cc' || echo '$(srcdir)/'`SynTree/Mutator.cc
-
-SynTree/driver_cfa_cpp-Mutator.obj: SynTree/Mutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Mutator.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Mutator.cc' object='SynTree/driver_cfa_cpp-Mutator.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
 
 SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Parser/ExpressionNode.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:17:07 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Sep 27 22:51:55 2017
-// Update Count     : 781
+// Last Modified On : Sat Mar  3 18:22:33 2018
+// Update Count     : 796
 //
 
@@ -58,4 +58,5 @@
 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
+static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
 
@@ -116,5 +117,5 @@
 
 	unsigned long long int v;							// converted integral value
-	size_t last = str.length() - 1;						// last character of constant
+	size_t last = str.length() - 1;						// last subscript of constant
 	Expression * ret;
 
@@ -129,8 +130,18 @@
 	} // if
 
-	if ( str[0] == '0' ) {								// octal/hex constant ?
+	// Cannot be "0"
+
+	if ( str[0] == '0' ) {								// radix character ?
 		dec = false;
-		if ( last != 0 && checkX( str[1] ) ) {			// hex constant ?
+		if ( checkX( str[1] ) ) {						// hex constant ?
 			sscanf( (char *)str.c_str(), "%llx", &v );
+			//printf( "%llx %llu\n", v, v );
+		} else if ( checkB( str[1] ) ) {				// binary constant ?
+			v = 0;
+			for ( unsigned int i = 2;; i += 1 ) {		// compute value
+				if ( str[i] == '1' ) v |= 1;
+			  if ( i == last ) break;
+				v <<= 1;
+			} // for
 			//printf( "%llx %llu\n", v, v );
 		} else {										// octal constant
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Parser/lex.ll	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Thu Feb 22 18:11:27 2018
- * Update Count     : 637
+ * Last Modified On : Sat Mar  3 18:38:16 2018
+ * Update Count     : 640
  */
 
@@ -77,4 +77,5 @@
 %}
 
+binary [0-1]
 octal [0-7]
 nonzero [1-9]
@@ -103,4 +104,8 @@
 nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
 decimal_constant {nonzero_digits}{integer_suffix_opt}
+
+binary_digits ({binary})|({binary}({binary}|"_")*{binary})
+binary_prefix "0"[bB]"_"?
+binary_constant {binary_prefix}{binary_digits}{integer_suffix_opt}
 
 hex_digits ({hex})|({hex}({hex}|"_")*{hex})
@@ -315,6 +320,7 @@
 
 				/* numeric constants */
+{binary_constant} { NUMERIC_RETURN(INTEGERconstant); }
+{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
 {decimal_constant} { NUMERIC_RETURN(INTEGERconstant); }
-{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
 {hex_constant}	{ NUMERIC_RETURN(INTEGERconstant); }
 {floating_decimal}	{ NUMERIC_RETURN(FLOATING_DECIMALconstant); } // must appear before floating_constant
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/ResolvExpr/Resolver.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -788,4 +788,5 @@
 		stmtExpr->accept( resolver );
 		stmtExpr->computeResult();
+		// xxx - aggregate the environments from all statements? Possibly in AlternativeFinder instead?
 	}
 
@@ -793,22 +794,22 @@
 		visit_children = false;
 		// xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
-		maybeAccept( ctorInit->get_ctor(), *visitor );
-		maybeAccept( ctorInit->get_dtor(), *visitor );
+		maybeAccept( ctorInit->ctor, *visitor );
+		maybeAccept( ctorInit->dtor, *visitor );
 
 		// found a constructor - can get rid of C-style initializer
-		delete ctorInit->get_init();
-		ctorInit->set_init( NULL );
+		delete ctorInit->init;
+		ctorInit->init = nullptr;
 
 		// intrinsic single parameter constructors and destructors do nothing. Since this was
 		// implicitly generated, there's no way for it to have side effects, so get rid of it
 		// to clean up generated code.
-		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
-			delete ctorInit->get_ctor();
-			ctorInit->set_ctor( NULL );
-		}
-
-		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
-			delete ctorInit->get_dtor();
-			ctorInit->set_dtor( NULL );
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
+			delete ctorInit->ctor;
+			ctorInit->ctor = nullptr;
+		}
+
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
+			delete ctorInit->dtor;
+			ctorInit->dtor = nullptr;
 		}
 
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -118,4 +118,18 @@
 			env.push_back( newClass );
 		} // for
+	}
+
+	void TypeEnvironment::add( const TypeSubstitution & sub ) {
+		EqvClass newClass;
+		for ( auto p : sub ) {
+			newClass.vars.insert( p.first );
+			newClass.type = p.second->clone();
+			newClass.allowWidening = false;
+			// Minimal assumptions. Not technically correct, but might be good enough, and
+			// is the best we can do at the moment since information is lost in the
+			// transition to TypeSubstitution
+			newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false };
+			add( newClass );
+		}
 	}
 
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/ResolvExpr/TypeEnvironment.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -76,4 +76,5 @@
 		void add( const EqvClass &eqvClass );
 		void add( const Type::ForallList &tyDecls );
+		void add( const TypeSubstitution & sub );
 		template< typename SynTreeClass > int apply( SynTreeClass *&type ) const;
 		template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const;
Index: c/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ 	(revision )
@@ -1,127 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Mutator.cc --
-//
-// Author           : Richard C. Bilson
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 15:39:37 2017
-// Update Count     : 27
-//
-
-#include <cassert>             // for assert
-#include <list>                // for list
-
-#include "Attribute.h"         // for Attribute
-#include "Declaration.h"       // for ObjectDecl, Declaration, DeclarationWi...
-#include "Expression.h"        // for Expression, ConstantExpr, ConditionalExpr
-#include "Initializer.h"       // for ConstructorInit, Initializer, Designation
-#include "Mutator.h"
-#include "Statement.h"         // for Statement, CatchStmt, AsmStmt, ForStmt
-#include "Type.h"              // for Type, Type::ForallList, AttrType, Arra...
-#include "TypeSubstitution.h"  // for TypeSubstitution
-
-class Constant;
-class Subrange;
-
-Mutator::Mutator() {}
-
-Mutator::~Mutator() {}
-
-Type * Mutator::mutate( TupleType *tupleType ) {
-	mutateAll( tupleType->get_forall(), *this );
-	mutateAll( tupleType->get_types(), *this );
-	mutateAll( tupleType->get_members(), *this );
-	return tupleType;
-}
-
-Type * Mutator::mutate( TypeofType *typeofType ) {
-	assert( typeofType->get_expr() );
-	typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) );
-	return typeofType;
-}
-
-Type * Mutator::mutate( AttrType *attrType ) {
-	if ( attrType->get_isType() ) {
-		assert( attrType->get_type() );
-		attrType->set_type( attrType->get_type()->acceptMutator( *this ) );
-	} else {
-		assert( attrType->get_expr() );
-		attrType->set_expr( attrType->get_expr()->acceptMutator( *this ) );
-	}
-	return attrType;
-}
-
-Type * Mutator::mutate( VarArgsType *varArgsType ) {
-	mutateAll( varArgsType->get_forall(), *this );
-	return varArgsType;
-}
-
-Type * Mutator::mutate( ZeroType *zeroType ) {
-	mutateAll( zeroType->get_forall(), *this );
-	return zeroType;
-}
-
-Type * Mutator::mutate( OneType *oneType ) {
-	mutateAll( oneType->get_forall(), *this );
-	return oneType;
-}
-
-
-Designation * Mutator::mutate( Designation * designation ) {
-	mutateAll( designation->get_designators(), *this );
-	return designation;
-}
-
-Initializer * Mutator::mutate( SingleInit *singleInit ) {
-	singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
-	return singleInit;
-}
-
-Initializer * Mutator::mutate( ListInit *listInit ) {
-	mutateAll( listInit->get_designations(), *this );
-	mutateAll( listInit->get_initializers(), *this );
-	return listInit;
-}
-
-Initializer * Mutator::mutate( ConstructorInit *ctorInit ) {
-	ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
-	ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) );
-	ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
-	return ctorInit;
-}
-
-
-Subrange * Mutator::mutate( Subrange *subrange ) {
-	return subrange;
-}
-
-
-Constant * Mutator::mutate( Constant *constant ) {
-	return constant;
-}
-
-Attribute * Mutator::mutate( Attribute * attribute ) {
-	mutateAll( attribute->parameters, *this );
-	return attribute;
-}
-
-TypeSubstitution * Mutator::mutate( TypeSubstitution * sub ) {
-	for ( auto & p : sub->typeEnv ) {
-		p.second = maybeMutate( p.second, *this );
-	}
-	for ( auto & p : sub->varEnv ) {
-		p.second = maybeMutate( p.second, *this );
-	}
-	return sub;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/Mutator.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -22,6 +22,6 @@
 class Mutator {
   protected:
-	Mutator();
-	virtual ~Mutator();
+	Mutator() = default;
+	virtual ~Mutator() = default;
   public:
 	virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) = 0;
Index: src/SynTree/TypeSubstitution.cc
===================================================================
--- src/SynTree/TypeSubstitution.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/TypeSubstitution.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -104,4 +104,28 @@
 bool TypeSubstitution::empty() const {
 	return typeEnv.empty() && varEnv.empty();
+}
+
+namespace {
+	struct EnvTrimmer {
+		TypeSubstitution * env, * newEnv;
+		EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
+		void previsit( TypeDecl * tyDecl ) {
+			// transfer known bindings for seen type variables
+			if ( Type * t = env->lookup( tyDecl->name ) ) {
+				newEnv->add( tyDecl->name, t );
+			}
+		}
+	};
+} // namespace
+
+/// reduce environment to just the parts that are referenced in a given expression
+TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {
+	if ( env ) {
+		TypeSubstitution * newEnv = new TypeSubstitution();
+		PassVisitor<EnvTrimmer> trimmer( env, newEnv );
+		expr->accept( trimmer );
+		return newEnv;
+	}
+	return nullptr;
 }
 
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/TypeSubstitution.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -55,4 +55,7 @@
 	void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
 
+	/// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
+	static TypeSubstitution * newFromExpr( Expression * expr, TypeSubstitution * env );
+
 	void normalize();
 
@@ -79,4 +82,11 @@
 	TypeEnvType typeEnv;
 	VarEnvType varEnv;
+
+  public:
+	// has to come after declaration of typeEnv
+	auto begin()       -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
+	auto   end()       -> decltype( typeEnv.  end() ) { return typeEnv.  end(); }
+	auto begin() const -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
+	auto   end() const -> decltype( typeEnv.  end() ) { return typeEnv.  end(); }
 };
 
Index: c/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ 	(revision )
@@ -1,100 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Visitor.cc --
-//
-// Author           : Richard C. Bilson
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 15:39:38 2017
-// Update Count     : 29
-//
-
-#include <cassert>        // for assert
-#include <list>           // for list
-
-#include "Attribute.h"    // for Attribute
-#include "Constant.h"     // for Constant
-#include "Declaration.h"  // for DeclarationWithType, ObjectDecl, Declaration
-#include "Expression.h"   // for Expression, ConstantExpr, ImplicitCopyCtorExpr
-#include "Initializer.h"  // for Initializer, Designation, ConstructorInit
-#include "Statement.h"    // for Statement, CatchStmt, AsmStmt, CompoundStmt
-#include "Type.h"         // for Type, Type::ForallList, AttrType, FunctionType
-#include "Visitor.h"
-
-class Subrange;
-
-Visitor::Visitor() {}
-
-Visitor::~Visitor() {}
-
-void Visitor::visit( TupleType *tupleType ) {
-	acceptAll( tupleType->get_forall(), *this );
-	acceptAll( tupleType->get_types(), *this );
-	acceptAll( tupleType->get_members(), *this );
-}
-
-void Visitor::visit( TypeofType *typeofType ) {
-	assert( typeofType->get_expr() );
-	typeofType->get_expr()->accept( *this );
-}
-
-void Visitor::visit( AttrType *attrType ) {
-	if ( attrType->get_isType() ) {
-		assert( attrType->get_type() );
-		attrType->get_type()->accept( *this );
-	} else {
-		assert( attrType->get_expr() );
-		attrType->get_expr()->accept( *this );
-	} // if
-}
-
-void Visitor::visit( VarArgsType *varArgsType ) {
-	acceptAll( varArgsType->get_forall(), *this );
-}
-
-void Visitor::visit( ZeroType *zeroType ) {
-	acceptAll( zeroType->get_forall(), *this );
-}
-
-void Visitor::visit( OneType *oneType ) {
-	acceptAll( oneType->get_forall(), *this );
-}
-
-void Visitor::visit( Designation * designation ) {
-	acceptAll( designation->get_designators(), *this );
-}
-
-void Visitor::visit( SingleInit *singleInit ) {
-	singleInit->get_value()->accept( *this );
-}
-
-void Visitor::visit( ListInit *listInit ) {
-	acceptAll( listInit->get_designations(), *this );
-	acceptAll( listInit->get_initializers(), *this );
-}
-
-void Visitor::visit( ConstructorInit *ctorInit ) {
-	maybeAccept( ctorInit->get_ctor(), *this );
-	maybeAccept( ctorInit->get_dtor(), *this );
-	maybeAccept( ctorInit->get_init(), *this );
-}
-
-
-void Visitor::visit( Subrange * ) {}
-
-
-void Visitor::visit( Constant * ) {}
-
-void Visitor::visit( Attribute * attribute ) {
-	acceptAll( attribute->parameters, *this );
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/Visitor.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -21,6 +21,6 @@
 class Visitor {
   protected:
-	Visitor();
-	virtual ~Visitor();
+	Visitor() = default;
+	virtual ~Visitor() = default;
   public:
 	// visit: Default implementation of all functions visits the children
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/module.mk	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -46,6 +46,4 @@
        SynTree/TypeDecl.cc \
        SynTree/Initializer.cc \
-       SynTree/Visitor.cc \
-       SynTree/Mutator.cc \
        SynTree/TypeSubstitution.cc \
        SynTree/Attribute.cc \
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Tuples/TupleAssignment.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -281,12 +281,17 @@
 	}
 
-	// removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator.
+	// removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator, and adds the bindings to the compositeEnv
 	// xxx - maybe this should happen in alternative finder for every StmtExpr?
-	// xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv
 	struct EnvRemover {
 		void previsit( ExprStmt * stmt ) {
-			delete stmt->expr->env;
-			stmt->expr->env = nullptr;
-		}
+			assert( compositeEnv );
+			if ( stmt->expr->env ) {
+				compositeEnv->add( *stmt->expr->env );
+				delete stmt->expr->env;
+				stmt->expr->env = nullptr;
+			}
+		}
+
+		ResolvExpr::TypeEnvironment * compositeEnv = nullptr;
 	};
 
@@ -300,4 +305,5 @@
 			ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
 			PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
+			rm.pass.compositeEnv = &compositeEnv;
 			ctorInit->accept( rm );
 		}
Index: src/libcfa/limits
===================================================================
--- src/libcfa/limits	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/libcfa/limits	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 18:06:52 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul  7 09:33:57 2017
-// Update Count     : 7
+// Last Modified On : Thu Mar  1 16:20:54 2018
+// Update Count     : 13
 //
 
@@ -18,9 +18,17 @@
 // Integral Constants
 
+extern const signed char MIN;
+extern const unsigned char MIN;
 extern const short int MIN;
+extern const unsigned short int MIN;
 extern const int MIN;
+extern const unsigned int MIN;
 extern const long int MIN;
+extern const unsigned long int MIN;
 extern const long long int MIN;
+extern const unsigned long long int MIN;
 
+extern const signed char MAX;
+extern const unsigned char MAX;
 extern const short int MAX;
 extern const unsigned short int MAX;
@@ -33,4 +41,18 @@
 
 // Floating-Point Constants
+
+extern const float MIN;
+extern const double MIN;
+extern const long double MIN;
+extern const float _Complex MIN;
+extern const double _Complex MIN;
+extern const long double _Complex MIN;
+
+extern const float MAX;
+extern const double MAX;
+extern const long double MAX;
+extern const float _Complex MAX;
+extern const double _Complex MAX;
+extern const long double _Complex MAX;
 
 extern const float PI;									// pi
@@ -55,17 +77,24 @@
 extern const long double _2_SQRT_PI;					// 2 / sqrt(pi)
 
-extern const _Complex PI;								// pi
-extern const _Complex PI_2;								// pi / 2
-extern const _Complex PI_4;								// pi / 4
-extern const _Complex _1_PI;							// 1 / pi
-extern const _Complex _2_PI;							// 2 / pi
-extern const _Complex _2_SQRT_PI;						// 2 / sqrt(pi)
+extern const float _Complex PI;							// pi
+extern const float _Complex PI_2;						// pi / 2
+extern const float _Complex PI_4;						// pi / 4
+extern const float _Complex _1_PI;						// 1 / pi
+extern const float _Complex _2_PI;						// 2 / pi
+extern const float _Complex _2_SQRT_PI;					// 2 / sqrt(pi)
 
-extern const long _Complex PI;							// pi
-extern const long _Complex PI_2;						// pi / 2
-extern const long _Complex PI_4;						// pi / 4
-extern const long _Complex _1_PI;						// 1 / pi
-extern const long _Complex _2_PI;						// 2 / pi
-extern const long _Complex _2_SQRT_PI;					// 2 / sqrt(pi)
+extern const double _Complex PI;						// pi
+extern const double _Complex PI_2;						// pi / 2
+extern const double _Complex PI_4;						// pi / 4
+extern const double _Complex _1_PI;						// 1 / pi
+extern const double _Complex _2_PI;						// 2 / pi
+extern const double _Complex _2_SQRT_PI;				// 2 / sqrt(pi)
+
+extern const long double _Complex PI;					// pi
+extern const long double _Complex PI_2;					// pi / 2
+extern const long double _Complex PI_4;					// pi / 4
+extern const long double _Complex _1_PI;				// 1 / pi
+extern const long double _Complex _2_PI;				// 2 / pi
+extern const long double _Complex _2_SQRT_PI;			// 2 / sqrt(pi)
 
 extern const float E;									// e
@@ -93,19 +122,27 @@
 extern const long double _1_SQRT_2;						// 1/sqrt(2)
 
-extern const _Complex E;								// e
-extern const _Complex LOG2_E;							// log_2(e)
-extern const _Complex LOG10_E;							// log_10(e)
-extern const _Complex LN_2;								// log_e(2)
-extern const _Complex LN_10;							// log_e(10)
-extern const _Complex SQRT_2;							// sqrt(2)
-extern const _Complex _1_SQRT_2;						// 1 / sqrt(2)
+extern const float _Complex E;							// e
+extern const float _Complex LOG2_E;						// log_2(e)
+extern const float _Complex LOG10_E;					// log_10(e)
+extern const float _Complex LN_2;						// log_e(2)
+extern const float _Complex LN_10;						// log_e(10)
+extern const float _Complex SQRT_2;						// sqrt(2)
+extern const float _Complex _1_SQRT_2;					// 1 / sqrt(2)
 
-extern const long _Complex E;							// e
-extern const long _Complex LOG2_E;						// log_2(e)
-extern const long _Complex LOG10_E;						// log_10(e)
-extern const long _Complex LN_2;						// log_e(2)
-extern const long _Complex LN_10;						// log_e(10)
-extern const long _Complex SQRT_2;						// sqrt(2)
-extern const long _Complex _1_SQRT_2;					// 1 / sqrt(2)
+extern const double _Complex E;							// e
+extern const double _Complex LOG2_E;					// log_2(e)
+extern const double _Complex LOG10_E;					// log_10(e)
+extern const double _Complex LN_2;						// log_e(2)
+extern const double _Complex LN_10;						// log_e(10)
+extern const double _Complex SQRT_2;					// sqrt(2)
+extern const double _Complex _1_SQRT_2;					// 1 / sqrt(2)
+
+extern const long double _Complex E;					// e
+extern const long double _Complex LOG2_E;				// log_2(e)
+extern const long double _Complex LOG10_E;				// log_10(e)
+extern const long double _Complex LN_2;					// log_e(2)
+extern const long double _Complex LN_10;				// log_e(10)
+extern const long double _Complex SQRT_2;				// sqrt(2)
+extern const long double _Complex _1_SQRT_2;			// 1 / sqrt(2)
 
 // Local Variables: //
Index: src/libcfa/limits.c
===================================================================
--- src/libcfa/limits.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/libcfa/limits.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,110 +10,144 @@
 // Created On       : Wed Apr  6 18:06:52 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Sep 12 10:34:48 2016
-// Update Count     : 17
+// Last Modified On : Thu Mar  1 16:22:51 2018
+// Update Count     : 74
 // 
 
+#include <limits.h>
+#include <float.h>
+#define __USE_GNU										// get M_* constants
+#include <math.h>
+#include <complex.h>
 #include "limits"
 
 // Integral Constants
 
-const short int MIN = -32768;
-const int MIN = -2147483648;
-#if __WORDSIZE == 64
-const long int MIN = -9223372036854775807L - 1L;
-#else
-const long int MIN = (int)MIN;
-#endif // M64
-const long long int MIN = -9223372036854775807LL - 1LL;
+const signed char MIN = SCHAR_MIN;
+const unsigned char MIN = 0;
+const short int MIN = SHRT_MIN;
+const unsigned short int MIN = 0;
+const int MIN = INT_MIN;
+const unsigned int MIN = 0;
+const long int MIN = LONG_MIN;
+const unsigned long int MIN = 0;
+const long long int MIN = LLONG_MIN;
+const unsigned long long int MIN = 0;
 
-const short int MAX = 32767;
-const unsigned short int MAX = 65535;
-const int MAX = 2147483647;
-const unsigned int MAX = 4294967295_U;
-#if __WORDSIZE == 64
-const long int MAX = 9223372036854775807_L;
-#else
-const long int MAX = (int)MAX;
-#endif // M64
-const unsigned long int MAX = 4294967295_U;
-const long long int MAX = 9223372036854775807_LL;
-const unsigned long long int MAX = 18446744073709551615_ULL;
+const signed char MAX = SCHAR_MAX;
+const unsigned char MAX = UCHAR_MAX;
+const short int MAX = SHRT_MAX;
+const unsigned short int MAX = USHRT_MAX;
+const int MAX = INT_MAX;
+const unsigned int MAX = UINT_MAX;
+const long int MAX = LONG_MAX;
+const unsigned long int MAX = ULONG_MAX;
+const long long int MAX = LLONG_MAX;
+const unsigned long long int MAX = ULLONG_MAX;
 
 // Floating-Point Constants
 
-const float PI = 3.141592_F;							// pi
-const float PI_2 = 1.570796_F;							// pi / 2
-const float PI_4 = 0.7853981_F;							// pi / 4
-const float _1_PI = 0.3183098_F;						// 1 / pi
-const float _2_PI = 0.6366197_F;						// 2 / pi
-const float _2_SQRT_PI = 1.128379_F;					// 2 / sqrt(pi)
+const float MIN = FLT_MIN;
+const double MIN = DBL_MIN;
+const long double MIN = LDBL_MIN;
+const float _Complex MIN = __FLT_MIN__ + __FLT_MIN__ * I;
+const double _Complex MIN = DBL_MIN +  DBL_MIN * I;
+const long double _Complex MIN = LDBL_MIN + LDBL_MIN * I;
 
-const double PI = 3.14159265358979323846_D;				// pi
-const double PI_2 = 1.57079632679489661923_D;			// pi / 2
-const double PI_4 = 0.78539816339744830962_D;			// pi / 4
-const double _1_PI = 0.31830988618379067154_D;			// 1 / pi
-const double _2_PI = 0.63661977236758134308_D;			// 2 / pi
-const double _2_SQRT_PI = 1.12837916709551257390_D;		// 2 / sqrt(pi)
+const float MAX = FLT_MAX;
+const double MAX = DBL_MAX;
+const long double MAX = LDBL_MAX;
+const float _Complex MAX = FLT_MAX + FLT_MAX * I;
+const double _Complex MAX = DBL_MAX + DBL_MAX * I;
+const long double _Complex MAX = LDBL_MAX + LDBL_MAX * I;
 
-const long double PI = 3.1415926535897932384626433832795029_DL; // pi
-const long double PI_2 = 1.5707963267948966192313216916397514_DL; // pi / 2
-const long double PI_4 = 0.7853981633974483096156608458198757_DL; // pi / 4
-const long double _1_PI = 0.3183098861837906715377675267450287_DL; // 1 / pi
-const long double _2_PI = 0.6366197723675813430755350534900574_DL; // 2 / pi
-const long double _2_SQRT_PI = 1.1283791670955125738961589031215452_DL; // 2 / sqrt(pi)
+const float PI = (float)M_PI;							// pi
+const float PI_2 = (float)M_PI_2;						// pi / 2
+const float PI_4 = (float)M_PI_4;						// pi / 4
+const float _1_PI = (float)M_1_PI;						// 1 / pi
+const float _2_PI = (float)M_2_PI;						// 2 / pi
+const float _2_SQRT_PI = (float)M_2_SQRTPI;				// 2 / sqrt(pi)
 
-const double _Complex PI = 3.14159265358979323846_D+0.0_iD;	// pi
-const double _Complex PI_2 = 1.57079632679489661923_D+0.0_iD; // pi / 2
-const double _Complex PI_4 = 0.78539816339744830962_D+0.0_iD; // pi / 4
-const double _Complex _1_PI = 0.31830988618379067154_D+0.0_iD; // 1 / pi
-const double _Complex _2_PI = 0.63661977236758134308_D+0.0_iD; // 2 / pi
-const double _Complex _2_SQRT_PI = 1.12837916709551257390_D+0.0_iD; // 2 / sqrt(pi)
+const double PI = M_PI;									// pi
+const double PI_2 = M_PI_2;								// pi / 2
+const double PI_4 = M_PI_4;								// pi / 4
+const double _1_PI = M_1_PI;							// 1 / pi
+const double _2_PI = M_2_PI;							// 2 / pi
+const double _2_SQRT_PI = M_2_SQRTPI;					// 2 / sqrt(pi)
 
-const long double _Complex PI = 3.1415926535897932384626433832795029_L+0.0iL; // pi
-const long double _Complex PI_2 = 1.5707963267948966192313216916397514_L+0.0iL; // pi / 2
-const long double _Complex PI_4 = 0.7853981633974483096156608458198757_L+0.0iL; // pi / 4
-const long double _Complex _1_PI = 0.3183098861837906715377675267450287_L+0.0iL; // 1 / pi
-const long double _Complex _2_PI = 0.6366197723675813430755350534900574_L+0.0iL; // 2 / pi
-const long double _Complex _2_SQRT_PI = 1.1283791670955125738961589031215452_L+0.0iL; // 2 / sqrt(pi)
+const long double PI = M_PIl;							// pi
+const long double PI_2 = M_PI_2l;						// pi / 2
+const long double PI_4 = M_PI_4l;						// pi / 4
+const long double _1_PI = M_1_PIl;						// 1 / pi
+const long double _2_PI = M_2_PIl;						// 2 / pi
+const long double _2_SQRT_PI = M_2_SQRTPIl;				// 2 / sqrt(pi)
 
-const float E = 2.718281;								// e
-const float LOG2_E = 1.442695;							// log_2(e)
-const float LOG10_E = 0.4342944;						// log_10(e)
-const float LN_2 = 0.6931471;							// log_e(2)
-const float LN_10 = 2.302585;							// log_e(10)
-const float SQRT_2 = 1.414213;							// sqrt(2)
-const float _1_SQRT_2 = 0.7071067;						// 1 / sqrt(2)
+const float _Complex PI = (float)M_PI + 0.0_iF;			// pi
+const float _Complex PI_2 = (float)M_PI_2 + 0.0_iF;		// pi / 2
+const float _Complex PI_4 = (float)M_PI_4 + 0.0_iF;		// pi / 4
+const float _Complex _1_PI = (float)M_1_PI + 0.0_iF;	// 1 / pi
+const float _Complex _2_PI = (float)M_2_PI + 0.0_iF;	// 2 / pi
+const float _Complex _2_SQRT_PI = (float)M_2_SQRTPI + 0.0_iF; // 2 / sqrt(pi)
 
-const double E = 2.7182818284590452354_D;				// e
-const double LOG2_E = 1.4426950408889634074_D;			// log_2(e)
-const double LOG10_E = 0.43429448190325182765_D;		// log_10(e)
-const double LN_2 = 0.69314718055994530942_D;			// log_e(2)
-const double LN_10 = 2.30258509299404568402_D;			// log_e(10)
-const double SQRT_2 = 1.41421356237309504880_D;			// sqrt(2)
-const double _1_SQRT_2 = 0.70710678118654752440_D;		// 1 / sqrt(2)
+const double _Complex PI = M_PI + 0.0_iD;				// pi
+const double _Complex PI_2 = M_PI_2 + 0.0_iD;			// pi / 2
+const double _Complex PI_4 = M_PI_4 + 0.0_iD;			// pi / 4
+const double _Complex _1_PI = M_1_PI + 0.0_iD;			// 1 / pi
+const double _Complex _2_PI = M_2_PI + 0.0_iD;			// 2 / pi
+const double _Complex _2_SQRT_PI = M_2_SQRTPI + 0.0_iD;	// 2 / sqrt(pi)
 
-const long double E = 2.7182818284590452353602874713526625_DL; // e
-const long double LOG2_E = 1.4426950408889634073599246810018921_DL; // log_2(e)
-const long double LOG10_E = 0.4342944819032518276511289189166051_DL; // log_10(e)
-const long double LN_2 = 0.6931471805599453094172321214581766_DL; // log_e(2)
-const long double LN_10 = 2.3025850929940456840179914546843642_DL; // log_e(10)
-const long double SQRT_2 = 1.4142135623730950488016887242096981_DL; // sqrt(2)
-const long double _1_SQRT_2 = 0.7071067811865475244008443621048490_DL; // 1/sqrt(2)
+const long double _Complex PI = M_PIl + 0.0_iL;			// pi
+const long double _Complex PI_2 = M_PI_2l + 0.0_iL;		// pi / 2
+const long double _Complex PI_4 = M_PI_4l + 0.0_iL;		// pi / 4
+const long double _Complex _1_PI = M_1_PIl + 0.0_iL;	// 1 / pi
+const long double _Complex _2_PI = M_2_PIl + 0.0_iL;	// 2 / pi
+const long double _Complex _2_SQRT_PI = M_2_SQRTPIl + 0.0_iL; // 2 / sqrt(pi)
 
-const double _Complex E = 2.7182818284590452354_D+0.0_iD; // e
-const double _Complex LOG2_E = 1.4426950408889634074_D+0.0_iD; // log_2(e)
-const double _Complex LOG10_E = 0.43429448190325182765_D+0.0_iD; // log_10(e)
-const double _Complex LN_2 = 0.69314718055994530942_D+0.0_iD; // log_e(2)
-const double _Complex LN_10 = 2.30258509299404568402_D+0.0_iD; // log_e(10)
-const double _Complex SQRT_2 = 1.41421356237309504880_D+0.0_iD; // sqrt(2)
-const double _Complex _1_SQRT_2 = 0.70710678118654752440_D+0.0_iD; // 1 / sqrt(2)
+const float E = (float)M_E;								// e
+const float LOG2_E = (float)M_LOG2E;					// log_2(e)
+const float LOG10_E = (float)M_LOG10E;					// log_10(e)
+const float LN_2 = (float)M_LN2;						// log_e(2)
+const float LN_10 = (float)M_LN10;						// log_e(10)
+const float SQRT_2 = (float)M_SQRT2;					// sqrt(2)
+const float _1_SQRT_2 = (float)M_SQRT1_2;				// 1 / sqrt(2)
 
-const long double _Complex E = 2.7182818284590452353602874713526625_L+0.0_iL; // e
-const long double _Complex LOG2_E = 1.4426950408889634073599246810018921_L+0.0_iL; // log_2(e)
-const long double _Complex LOG10_E = 0.4342944819032518276511289189166051_L+0.0_iL; // log_10(e)
-const long double _Complex LN_2 = 0.6931471805599453094172321214581766_L+0.0_iL; // log_e(2)
-const long double _Complex LN_10 = 2.3025850929940456840179914546843642_L+0.0_iL; // log_e(10)
-const long double _Complex SQRT_2 = 1.4142135623730950488016887242096981_L+0.0_iL; // sqrt(2)
-const long double _Complex _1_SQRT_2 = 0.7071067811865475244008443621048490_L+0.0_iL; // 1 / sqrt(2)
+const double E = M_E;									// e
+const double LOG2_E = M_LOG2E;							// log_2(e)
+const double LOG10_E = M_LOG10E;						// log_10(e)
+const double LN_2 = M_LN2;								// log_e(2)
+const double LN_10 = M_LN10;							// log_e(10)
+const double SQRT_2 = M_SQRT2;							// sqrt(2)
+const double _1_SQRT_2 = M_SQRT1_2;						// 1 / sqrt(2)
+
+const long double E = M_El;								// e
+const long double LOG2_E = M_LOG2El;					// log_2(e)
+const long double LOG10_E = M_LOG10El;					// log_10(e)
+const long double LN_2 = M_LN2l;						// log_e(2)
+const long double LN_10 = M_LN10l;						// log_e(10)
+const long double SQRT_2 = M_SQRT2l;					// sqrt(2)
+const long double _1_SQRT_2 = M_SQRT1_2l;				// 1 / sqrt(2)
+
+const float _Complex E = M_E + 0.0_iF;					// e
+const float _Complex LOG2_E = M_LOG2E + 0.0_iF;			// log_2(e)
+const float _Complex LOG10_E = M_LOG10E + 0.0_iF;		// log_10(e)
+const float _Complex LN_2 = M_LN2 + 0.0_iF;				// log_e(2)
+const float _Complex LN_10 = M_LN10 + 0.0_iF;			// log_e(10)
+const float _Complex SQRT_2 = M_SQRT2 + 0.0_iF;			// sqrt(2)
+const float _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iF;	// 1 / sqrt(2)
+
+const double _Complex E = M_E + 0.0_iD;					// e
+const double _Complex LOG2_E = M_LOG2E + 0.0_iD;		// log_2(e)
+const double _Complex LOG10_E = M_LOG10E + 0.0_iD;		// log_10(e)
+const double _Complex LN_2 = M_LN2 + 0.0_iD;			// log_e(2)
+const double _Complex LN_10 = M_LN10 + 0.0_iD;			// log_e(10)
+const double _Complex SQRT_2 = M_SQRT2 + 0.0_iD;		// sqrt(2)
+const double _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iD;	// 1 / sqrt(2)
+
+const long double _Complex E = M_El + 0.0_iL;			// e
+const long double _Complex LOG2_E = M_LOG2El + 0.0_iL;	// log_2(e)
+const long double _Complex LOG10_E = M_LOG10El + 0.0_iL; // log_10(e)
+const long double _Complex LN_2 = M_LN2l + 0.0_iL;		// log_e(2)
+const long double _Complex LN_10 = M_LN10l + 0.0_iL;	// log_e(10)
+const long double _Complex SQRT_2 = M_SQRT2l + 0.0_iL;	// sqrt(2)
+const long double _Complex _1_SQRT_2 = M_SQRT1_2l + 0.0_iL; // 1 / sqrt(2)
 
 // Local Variables: //
Index: src/tests/.expect/KRfunctions.x86.txt
===================================================================
--- src/tests/.expect/KRfunctions.x86.txt	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/.expect/KRfunctions.x86.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -82,7 +82,7 @@
     signed int __a__i_2;
     signed int __b__i_2;
-    signed int *(*_tmp_cp_ret0)(signed int __x__i_1, signed int __y__i_1);
-    ((void)(__x__PFPi_ii__2=(((void)(_tmp_cp_ret0=__f10__FPFPi_ii__iPiPid__1(3, (&__a__i_2), (&__b__i_2), 3.5))) , _tmp_cp_ret0)));
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    signed int *(*_tmp_cp_ret2)(signed int __x__i_1, signed int __y__i_1);
+    ((void)(__x__PFPi_ii__2=(((void)(_tmp_cp_ret2=__f10__FPFPi_ii__iPiPid__1(3, (&__a__i_2), (&__b__i_2), 3.5))) , _tmp_cp_ret2)));
+    ((void)(_tmp_cp_ret2) /* ^?{} */);
     const signed int __f1__FCi_iPiPi__2(signed int __a__i_2, signed int *__b__Pi_2, signed int *__c__Pi_2){
         __attribute__ ((unused)) const signed int ___retval_f1__Ci_2;
Index: src/tests/.expect/literals.x64.txt
===================================================================
--- src/tests/.expect/literals.x64.txt	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/.expect/literals.x64.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -522,4 +522,28 @@
 signed int __main__Fi___1(){
     __attribute__ ((unused)) signed int ___retval_main__i_1;
+    ((void)0b01101011);
+    ((void)0b01101011u);
+    ((void)0b01101011l);
+    ((void)0b01101011ll);
+    ((void)0b01101011ul);
+    ((void)0b01101011lu);
+    ((void)0b01101011ull);
+    ((void)0b01101011llu);
+    ((void)(+0b01101011));
+    ((void)(+0b01101011u));
+    ((void)(+0b01101011l));
+    ((void)(+0b01101011ll));
+    ((void)(+0b01101011ul));
+    ((void)(+0b01101011lu));
+    ((void)(+0b01101011ull));
+    ((void)(+0b01101011llu));
+    ((void)(-0b01101011));
+    ((void)(-0b01101011u));
+    ((void)(-0b01101011l));
+    ((void)(-0b01101011ll));
+    ((void)(-0b01101011ul));
+    ((void)(-0b01101011lu));
+    ((void)(-0b01101011ull));
+    ((void)(-0b01101011llu));
     ((void)01234567);
     ((void)01234567u);
@@ -1017,4 +1041,34 @@
     ((void)(-0X0123456789.0123456789P-09F));
     ((void)(-0X0123456789.0123456789P-09L));
+    ((void)((signed char )0b01101011));
+    ((void)((signed short int )0b01101011));
+    ((void)((signed int )0b01101011));
+    ((void)((signed long int )0b01101011));
+    ((void)((__int128 )0b01101011));
+    ((void)((unsigned char )0b01101011u));
+    ((void)((signed short int )0b01101011u));
+    ((void)((unsigned int )0b01101011u));
+    ((void)((signed long int )0b01101011u));
+    ((void)((__int128 )0b01101011u));
+    ((void)(+((signed int )((signed char )0b01101011))));
+    ((void)(+((signed int )((signed short int )0b01101011))));
+    ((void)(+((signed int )0b01101011)));
+    ((void)(+((signed long int )0b01101011)));
+    ((void)(+((float )((__int128 )0b01101011))));
+    ((void)(+((signed int )((unsigned char )0b01101011u))));
+    ((void)(+((signed int )((signed short int )0b01101011u))));
+    ((void)(+((unsigned int )0b01101011u)));
+    ((void)(+((signed long int )0b01101011u)));
+    ((void)(+((float )((__int128 )0b01101011u))));
+    ((void)(-((signed int )((signed char )0b01101011))));
+    ((void)(-((signed int )((signed short int )0b01101011))));
+    ((void)(-((signed int )0b01101011)));
+    ((void)(-((signed long int )0b01101011)));
+    ((void)(-((float )((__int128 )0b01101011))));
+    ((void)(-((signed int )((unsigned char )0b01101011u))));
+    ((void)(-((signed int )((signed short int )0b01101011u))));
+    ((void)(-((unsigned int )0b01101011u)));
+    ((void)(-((signed long int )0b01101011u)));
+    ((void)(-((float )((__int128 )0b01101011u))));
     ((void)((signed char )01234567));
     ((void)((signed short int )01234567));
Index: src/tests/.expect/user_literals.txt
===================================================================
--- src/tests/.expect/user_literals.txt	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/.expect/user_literals.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -1,8 +1,9 @@
 11.0714285714286
-11.07225
+15
 11.0714285714286
+24.8
+11.248
 11.0714285714286
-11.0714285714286
-22.0457142857143
+28.0657142857143
 secs 1
 secs 23
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/Makefile.am	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -123,2 +123,5 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
 
+# Warnings
+warnings/self-assignment: warnings/self-assignment.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/Makefile.in	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -800,4 +800,8 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
 
+# Warnings
+warnings/self-assignment: warnings/self-assignment.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/limits.c
===================================================================
--- src/tests/limits.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/limits.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Tue May 10 20:44:20 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 10 20:45:28 2016
-// Update Count     : 1
+// Last Modified On : Thu Mar  1 16:21:55 2018
+// Update Count     : 7
 //
 
@@ -18,9 +18,17 @@
 // Integral Constants
 
+signed char m = MIN;
+unsigned char m = MIN;
 short int m = MIN;
+unsigned short int m = MIN;
 int m = MIN;
+unsigned int m = MIN;
 long int m = MIN;
+unsigned long int m = MIN;
 long long int m = MIN;
+unsigned long long int m = MIN;
 
+signed char M = MAX;
+unsigned char M = MAX;
 short int M = MAX;
 unsigned short int M = MAX;
@@ -33,4 +41,18 @@
 
 // Floating-Point Constants
+
+float m = MIN;
+double m = MIN;
+long double m = MIN;
+float _Complex m = MIN;
+double _Complex m = MIN;
+long double _Complex m = MIN;
+
+float M = MAX;
+double M = MAX;
+long double M = MAX;
+float _Complex M = MAX;
+double _Complex M = MAX;
+long double _Complex M = MAX;
 
 float pi = PI;
@@ -55,17 +77,24 @@
 long double _2_sqrt_pi = _2_SQRT_PI;
 
-_Complex pi = PI;
-_Complex pi_2 = PI_2;
-_Complex pi_4 = PI_4;
-_Complex _1_pi = _1_PI;
-_Complex _2_pi = _2_PI;
-_Complex _2_sqrt_pi = _2_SQRT_PI;
+float _Complex pi = PI;
+float _Complex pi_2 = PI_2;
+float _Complex pi_4 = PI_4;
+float _Complex _1_pi = _1_PI;
+float _Complex _2_pi = _2_PI;
+float _Complex _2_sqrt_pi = _2_SQRT_PI;
 
-long _Complex pi = PI;
-long _Complex pi_2 = PI_2;
-long _Complex pi_4 = PI_4;
-long _Complex _1_pi = _1_PI;
-long _Complex _2_pi = _2_PI;
-long _Complex _2_sqrt_pi = _2_SQRT_PI;
+double _Complex pi = PI;
+double _Complex pi_2 = PI_2;
+double _Complex pi_4 = PI_4;
+double _Complex _1_pi = _1_PI;
+double _Complex _2_pi = _2_PI;
+double _Complex _2_sqrt_pi = _2_SQRT_PI;
+
+long double _Complex pi = PI;
+long double _Complex pi_2 = PI_2;
+long double _Complex pi_4 = PI_4;
+long double _Complex _1_pi = _1_PI;
+long double _Complex _2_pi = _2_PI;
+long double _Complex _2_sqrt_pi = _2_SQRT_PI;
 
 float e = E;
@@ -93,19 +122,27 @@
 long double _1_sqrt_2 = _1_SQRT_2;
 
-_Complex e = E;
-_Complex log2_e = LOG2_E;
-_Complex log10_e = LOG10_E;
-_Complex ln_2 = LN_2;
-_Complex ln_10 = LN_10;
-_Complex sqrt_2 = SQRT_2;
-_Complex _1_sqrt_2 = _1_SQRT_2;
+float _Complex e = E;
+float _Complex log2_e = LOG2_E;
+float _Complex log10_e = LOG10_E;
+float _Complex ln_2 = LN_2;
+float _Complex ln_10 = LN_10;
+float _Complex sqrt_2 = SQRT_2;
+float _Complex _1_sqrt_2 = _1_SQRT_2;
 
-long _Complex e = E;
-long _Complex log2_e = LOG2_E;
-long _Complex log10_e = LOG10_E;
-long _Complex ln_2 = LN_2;
-long _Complex ln_10 = LN_10;
-long _Complex sqrt_2 = SQRT_2;
-long _Complex _1_sqrt_2 = _1_SQRT_2;
+double _Complex e = E;
+double _Complex log2_e = LOG2_E;
+double _Complex log10_e = LOG10_E;
+double _Complex ln_2 = LN_2;
+double _Complex ln_10 = LN_10;
+double _Complex sqrt_2 = SQRT_2;
+double _Complex _1_sqrt_2 = _1_SQRT_2;
+
+long double _Complex e = E;
+long double _Complex log2_e = LOG2_E;
+long double _Complex log10_e = LOG10_E;
+long double _Complex ln_2 = LN_2;
+long double _Complex ln_10 = LN_10;
+long double _Complex sqrt_2 = SQRT_2;
+long double _Complex _1_sqrt_2 = _1_SQRT_2;
 
 int main(int argc, char const *argv[]) {
Index: src/tests/literals.c
===================================================================
--- src/tests/literals.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/literals.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  9 16:34:38 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Sep 25 20:26:00 2017
-// Update Count     : 132
+// Last Modified On : Sun Mar  4 10:41:31 2018
+// Update Count     : 134
 // 
 
@@ -31,4 +31,9 @@
 // integer literals
 
+	// binary
+	 0b01101011;   0b01101011u;   0b01101011l;   0b01101011ll;   0b01101011ul;   0b01101011lu;   0b01101011ull;   0b01101011llu;
+	+0b01101011;  +0b01101011u;  +0b01101011l;  +0b01101011ll;  +0b01101011ul;  +0b01101011lu;  +0b01101011ull;  +0b01101011llu;
+	-0b01101011;  -0b01101011u;  -0b01101011l;  -0b01101011ll;  -0b01101011ul;  -0b01101011lu;  -0b01101011ull;  -0b01101011llu;
+
 	// octal
 	 01234567;   01234567u;   01234567l;   01234567ll;   01234567ul;   01234567lu;   01234567ull;   01234567llu;
@@ -148,4 +153,9 @@
 #ifdef __CFA__
 // fixed-size length
+
+	// binary
+	 0b01101011_l8;   0b01101011_l16;   0b01101011_l32;   0b01101011_l64;   0b01101011_l128;   0b01101011_l8u;   0b01101011_ul16;   0b01101011_l32u;   0b01101011_ul64;   0b01101011_ul128;
+	+0b01101011_l8;  +0b01101011_l16;  +0b01101011_l32;  +0b01101011_l64;  +0b01101011_l128;  +0b01101011_l8u;  +0b01101011_ul16;  +0b01101011_l32u;  +0b01101011_ul64;  +0b01101011_ul128;
+	-0b01101011_l8;  -0b01101011_l16;  -0b01101011_l32;  -0b01101011_l64;  -0b01101011_l128;  -0b01101011_l8u;  -0b01101011_ul16;  -0b01101011_l32u;  -0b01101011_ul64;  -0b01101011_ul128;
 
 	// octal
Index: src/tests/user_literals.c
===================================================================
--- src/tests/user_literals.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/user_literals.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Wed Sep  6 21:40:50 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Dec  7 09:12:36 2017
-// Update Count     : 50
+// Last Modified On : Sun Mar  4 11:14:02 2018
+// Update Count     : 52
 // 
 
@@ -31,30 +31,31 @@
 
 
-struct Weight {
-	double stones;
-};
-void ?{}( Weight & w ) { w.stones = 0; }				// operations
+struct Weight { double stones; };
+void ?{}( Weight & w ) { w.stones = 0; }
 void ?{}( Weight & w, double w ) { w.stones = w; }
-Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
+Weight ?+?( Weight l, Weight r ) {
+	return (Weight){ l.stones + r.stones };
+}
 ofstream & ?|?( ofstream & os, Weight w ) { return os | w.stones; }
 
 Weight ?`st( double w ) { return (Weight){ w }; }		// backquote for user literals
 Weight ?`lb( double w ) { return (Weight){ w / 14.0 }; }
-Weight ?`kg( double w ) { return (Weight) { w * 0.1575}; }
-
+Weight ?`kg( double w ) { return (Weight) { w * 0.16 }; }
 
 int main() {
-	Weight w, hw = { 14 };								// 14 stone
-	w = 11`st + 1`lb;
+	Weight w, heavy = { 20 };							// 20 stone
+	w = 155`lb;
+	sout | w | endl;
+	w = 0b_1111`st;
+	sout | w | endl;
+	w = 0_233`lb;										// octal weight (155)
+	sout | w | endl;
+	w = 0x_9b_u`kg;
 	sout | w | endl;
 	w = 70.3`kg;
 	sout | w | endl;
-	w = 155`lb;
+	w = 11`st + 1`lb;
 	sout | w | endl;
-	w = 0x_9b_u`lb;										// hexadecimal unsigned weight (155)
-	sout | w | endl;
-	w = 0_233`lb;										// octal weight (155)
-	sout | w | endl;
-	w = 5`st + 8`kg + 25`lb + hw;
+	w = 5`st + 8`kg + 25`lb + heavy;
 	sout | w | endl;
 
Index: src/tests/warnings/.expect/self-assignment.txt
===================================================================
--- src/tests/warnings/.expect/self-assignment.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
+++ src/tests/warnings/.expect/self-assignment.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -0,0 +1,25 @@
+warnings/self-assignment.c:29:1 warning: self assignment of expression: Cast of:
+  Variable Expression: j: signed int
+... to:
+  reference to signed int
+warnings/self-assignment.c:30:1 warning: self assignment of expression: Cast of:
+  Variable Expression: s: instance of struct S with body 1 
+... to:
+  reference to instance of struct S with body 1 
+warnings/self-assignment.c:31:1 warning: self assignment of expression: Cast of:
+  Member Expression, with field: 
+    i: signed int
+  ... from aggregate: 
+    Variable Expression: s: instance of struct S with body 1 
+... to:
+  reference to signed int
+warnings/self-assignment.c:32:1 warning: self assignment of expression: Cast of:
+  Member Expression, with field: 
+    i: signed int
+  ... from aggregate: 
+    Member Expression, with field: 
+      s: instance of struct S with body 1 
+    ... from aggregate: 
+      Variable Expression: t: instance of struct T with body 1 
+... to:
+  reference to signed int
Index: src/tests/warnings/self-assignment.c
===================================================================
--- src/tests/warnings/self-assignment.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
+++ src/tests/warnings/self-assignment.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -0,0 +1,38 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// self-assignment.c --
+//
+// Author           : Rob Schluntz
+// Created On       : Thu Mar 1 13:53:57 2018
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Mar 1 13:53:57 2018
+// Update Count     : 2
+//
+
+struct S {
+  int i;
+};
+
+struct T {
+  S s;
+};
+
+int main() {
+  int j = 0;
+  S s = { 0 };
+  T t = { { 0 } };
+
+  j = j;
+  s = s;
+  s.i = s.i;
+  t.s.i = t.s.i;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa dtor-early-exit" //
+// End: //
