Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/CodeGen/CodeGenerator.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Aug 18 15:34:00 2017
-// Update Count     : 488
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun Sep  3 20:42:52 2017
+// Update Count     : 490
 //
 #include "CodeGenerator.h"
@@ -59,5 +59,5 @@
 
 	void CodeGenerator::asmName( DeclarationWithType * decl ) {
-		if ( ConstantExpr * asmName = decl->get_asmName() ) {
+		if ( ConstantExpr * asmName = dynamic_cast<ConstantExpr *>(decl->get_asmName()) ) {
 			output << " asm ( " << asmName->get_constant()->get_value() << " )";
 		} // if
@@ -195,7 +195,5 @@
 		}
 
-		output << kind;
-		if ( aggDecl->get_name() != "" )
-			output << aggDecl->get_name();
+		output << kind << aggDecl->get_name();
 
 		if ( aggDecl->has_body() ) {
@@ -233,6 +231,5 @@
 		genAttributes( enumDecl->get_attributes() );
 
-		if ( enumDecl->get_name() != "" )
-			output << enumDecl->get_name();
+		output << enumDecl->get_name();
 
 		std::list< Declaration* > &memb = enumDecl->get_members();
@@ -260,5 +257,9 @@
 	}
 
-	void CodeGenerator::visit( __attribute__((unused)) TraitDecl * traitDecl ) {}
+	void CodeGenerator::visit( TraitDecl * traitDecl ) {
+		assertf( ! genC, "TraitDecl nodes should not reach code generation." );
+		extension( traitDecl );
+		handleAggregate( traitDecl, "trait " );
+	}
 
 	void CodeGenerator::visit( TypedefDecl * typeDecl ) {
@@ -545,11 +546,11 @@
 		extension( addressExpr );
 		output << "(&";
-		// this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
-		if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
-			output << mangleName( variableExpr->get_var() );
-		} else {
-			addressExpr->get_arg()->accept( *this );
-		} // if
+		addressExpr->arg->accept( *this );
 		output << ")";
+	}
+
+	void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
+		extension( addressExpr );
+		output << "(&&" << addressExpr->arg << ")";
 	}
 
@@ -760,5 +761,5 @@
 		for ( Statement * stmt : stmts ) {
 			updateLocation( stmt );
-			output << printLabels( stmt->get_labels() );
+			output << indent << printLabels( stmt->get_labels() );
 			if ( i+1 == numStmts ) {
 				// last statement in a statement expression needs to be handled specially -
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/CodeGen/CodeGenerator.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -59,4 +59,5 @@
 		virtual void visit( NameExpr *nameExpr );
 		virtual void visit( AddressExpr *addressExpr );
+		virtual void visit( LabelAddressExpr *addressExpr );
 		virtual void visit( CastExpr *castExpr );
 		virtual void visit( VirtualCastExpr *castExpr );
Index: src/CodeGen/Generate.cc
===================================================================
--- src/CodeGen/Generate.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/CodeGen/Generate.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -21,4 +21,5 @@
 #include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
 #include "GenType.h"                 // for genPrettyType
+#include "Common/PassVisitor.h"      // for PassVisitor
 #include "Parser/LinkageSpec.h"      // for isBuiltin, isGeneratable
 #include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
@@ -29,5 +30,22 @@
 
 namespace CodeGen {
+	namespace {
+		/// Removes misc. nodes that should not exist in CodeGen
+		struct TreeCleaner {
+			void visit( CompoundStmt * stmt );
+
+			static bool shouldClean( Declaration * );
+		};
+
+		void cleanTree( std::list< Declaration * > & translationUnit ) {
+			PassVisitor<TreeCleaner> cleaner;
+			filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
+			acceptAll( translationUnit, cleaner );
+		} // cleanTree
+	} // namespace
+
 	void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks ) {
+		cleanTree( translationUnit );
+
 		CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks );
 		for ( auto & dcl : translationUnit ) {
@@ -52,4 +70,19 @@
 		os << std::endl;
 	}
+
+	namespace {
+		void TreeCleaner::visit( CompoundStmt * cstmt ) {
+			filter( cstmt->kids, [](Statement * stmt) {
+				if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
+					return shouldClean( declStmt->decl );
+				}
+				return false;
+			}, false );
+		}
+
+		bool TreeCleaner::shouldClean( Declaration * decl ) {
+			return dynamic_cast< TraitDecl * >( decl );
+		}
+	} // namespace
 } // namespace CodeGen
 
Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/CodeGen/OperatorTable.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -19,4 +19,5 @@
 
 #include "OperatorTable.h"
+#include "Common/utility.h"
 
 namespace CodeGen {
@@ -65,7 +66,4 @@
 			{	"?^=?",		"^=",	"_operator_bitxorassign",		OT_INFIXASSIGN		},
 			{	"?|=?",		"|=",	"_operator_bitorassign",		OT_INFIXASSIGN		},
-			{	"&&",		"&&",	"&&",							OT_LABELADDRESS		},
-			{	"0",		"0",	"_constant_zero",				OT_CONSTANT			},
-			{	"1",		"1",	"_constant_one",				OT_CONSTANT			}
 		};
 
@@ -86,6 +84,15 @@
 			initialize();
 		} // if
+
 		std::map< std::string, OperatorInfo >::const_iterator i = table.find( funcName );
 		if ( i == table.end() ) {
+			if ( isPrefix( funcName, "?`" ) ) {
+				// handle literal suffixes, which are user-defined postfix operators
+				info.inputName = funcName;
+				info.symbol = funcName.substr(2);
+				info.outputName = toString( "__operator_literal_", info.symbol );
+				info.type = OT_POSTFIX;
+				return true;
+			}
 			return false;
 		} else {
Index: src/Common/CodeLocation.h
===================================================================
--- src/Common/CodeLocation.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Common/CodeLocation.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Thr Aug 17 11:23:00 2017
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 14:07:00 2017
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 12:46:01 2017
+// Update Count     : 2
 //
 
@@ -66,5 +66,6 @@
 
 inline std::string to_string( const CodeLocation& location ) {
-    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
+    // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
+    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + ":1 " : "";
 }
 
Index: src/Common/Debug.h
===================================================================
--- src/Common/Debug.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/Common/Debug.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,42 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Debug.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Fri Sep 1 11:09:14 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri Sep 1 11:09:36 2017
+// Update Count     : 2
+//
+
+#pragma once
+
+#include <string>
+#include <list>
+#include <iostream>
+
+#include "CodeGen/Generate.h"
+#include "Parser/LinkageSpec.h"
+#include "SynTree/Declaration.h"
+
+/// debug codegen a translation unit
+static inline void debugCodeGen( const std::list< Declaration * > & translationUnit, const std::string & label ) {
+	std::list< Declaration * > decls;
+
+	filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) {
+		return ! LinkageSpec::isBuiltin( decl->get_linkage() );
+	});
+
+	std::cerr << "======" << label << "======" << std::endl;
+	CodeGen::generate( decls, std::cerr, false, true );
+} // dump
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Common/SemanticError.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,21 +10,16 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:21:25 2015
-// Update Count     : 1
+// Last Modified On : Tue Aug 29 18:17:35 2017
+// Update Count     : 3
 //
 
-#include <cstdio>            // for fileno, stderr
-#include <unistd.h>          // for isatty
-#include <iostream>          // for basic_ostream, operator<<, ostream
-#include <list>              // for list, _List_iterator
-#include <string>            // for string, operator<<, operator+, to_string
+#include <cstdio>										// for fileno, stderr
+#include <unistd.h>										// for isatty
+#include <iostream>										// for basic_ostream, operator<<, ostream
+#include <list>											// for list, _List_iterator
+#include <string>										// for string, operator<<, operator+, to_string
 
-#include "Common/utility.h"  // for to_string, CodeLocation (ptr only)
+#include "Common/utility.h"								// for to_string, CodeLocation (ptr only)
 #include "SemanticError.h"
-
-inline const std::string& error_str() {
-	static std::string str = isatty( fileno(stderr) ) ? "\e[31merror:\e[39m " : "error: ";
-	return str;
-}
 
 SemanticError::SemanticError() {
@@ -49,6 +44,6 @@
 void SemanticError::print( std::ostream &os ) {
 	using std::to_string;
-	for(auto err : errors) {
-		os << to_string( err.location ) << err.description << '\n';
+	for( auto err : errors ) {
+		os << to_string( err.location ) << err.description << std::endl;
 	}
 }
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Common/SemanticError.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,17 +9,18 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 14:01:00 2017
-// Update Count     : 7
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Aug 29 22:03:36 2017
+// Update Count     : 17
 //
 
 #pragma once
 
-#include <exception>  // for exception
-#include <iostream>   // for ostream
-#include <list>       // for list
-#include <string>     // for string
+#include <exception>									// for exception
+#include <iostream>										// for ostream
+#include <list>											// for list
+#include <string>										// for string
+#include <unistd.h>										// for isatty
 
-#include "CodeLocation.h"  // for CodeLocation, toString
+#include "CodeLocation.h"								// for CodeLocation, toString
 
 struct error {
@@ -28,7 +29,7 @@
 
 	error() = default;
-	error( const std::string& str ) : description( str ) {}
+	error( const std::string & str ) : description( str ) {}
 
-	void maybeSet( const CodeLocation& location ) {
+	void maybeSet( const CodeLocation & location ) {
 		if( this->location.linenumber < 0 ) {
 			this->location = location;
@@ -41,15 +42,20 @@
 	SemanticError();
 	SemanticError( std::string error );
-	template< typename T > SemanticError( const std::string &error, const T *obj );
+	template< typename T > SemanticError( const std::string & error, const T * obj );
 	~SemanticError() throw() {}
 
-	void append( SemanticError &other );
+	static inline const std::string & error_str() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
+		return str;
+	}
+
+	void append( SemanticError & other );
 	void append( const std::string & );
 	bool isEmpty() const;
-	void print( std::ostream &os );
+	void print( std::ostream & os );
 
-	void set_location( const CodeLocation& location );
-	// constructs an exception using the given message and the printed
-	// representation of the obj (T must have a print method)
+	void set_location( const CodeLocation & location );
+	// constructs an exception using the given message and the printed representation of the obj (T must have a print
+	// method)
   private:
 	std::list< error > errors;
@@ -57,5 +63,5 @@
 
 template< typename T >
-SemanticError::SemanticError( const std::string &error, const T *obj ) {
+SemanticError::SemanticError( const std::string & error, const T * obj ) {
 	append( toString( error, obj ) );
 }
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Common/utility.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -174,4 +174,19 @@
 }
 
+template <typename E, typename UnaryPredicate, template< typename, typename...> class Container, typename... Args >
+void filter( Container< E *, Args... > & container, UnaryPredicate pred, bool doDelete ) {
+	auto i = begin( container );
+	while ( i != end( container ) ) {
+		auto it = next( i );
+		if ( pred( *i ) ) {
+			if ( doDelete ) {
+				delete *i;
+			} // if
+			container.erase( i );
+		} // if
+		i = it;
+	} // while
+}
+
 template< typename... Args >
 auto zip(Args&&... args) -> decltype(zipWith(std::forward<Args>(args)..., std::make_pair)) {
@@ -207,4 +222,11 @@
 	std::cerr << "Warning: ";
 	warn_single( params... );
+}
+
+/// determines if `pref` is a prefix of `str`
+static inline bool isPrefix( const std::string & str, const std::string & pref ) {
+	if ( pref.size() > str.size() ) return false;
+	auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
+	return its.first == pref.end();
 }
 
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/GenPoly/Box.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -141,4 +141,5 @@
 			virtual StructDecl *mutate( StructDecl *structDecl ) override;
 			virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
+			virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
 			virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
 			virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
@@ -216,5 +217,4 @@
 		  private:
 		};
-
 	} // anonymous namespace
 
@@ -896,5 +896,4 @@
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
 				bodyStmt = new ExprStmt( noLabels, adapteeApp );
-//			} else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
 			} else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
 				// return type T
@@ -1299,11 +1298,4 @@
 		}
 
-		/// determines if `pref` is a prefix of `str`
-		bool isPrefix( const std::string & str, const std::string & pref ) {
-			if ( pref.size() > str.size() ) return false;
-			auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
-			return its.first == pref.end();
-		}
-
 		DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
 			functionDecl = safe_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
@@ -1352,4 +1344,8 @@
 		}
 
+		TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
+			return handleAggDecl( aggDecl );
+		}
+
 		TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
 			addToTyVarMap( typeDecl, scopeTyVars );
@@ -1377,4 +1373,5 @@
 		Type *Pass2::mutate( FunctionType *funcType ) {
 			scopeTyVars.beginScope();
+
 			makeTyVarMap( funcType, scopeTyVars );
 
@@ -1550,13 +1547,11 @@
 					// (alloca was previously used, but can't be safely used in loops)
 					Type *declType = objectDecl->get_type();
-					std::string bufName = bufNamer.newName();
-					ObjectDecl *newBuf = new ObjectDecl( bufName, Type::StorageClasses(), LinkageSpec::C, 0,
+					ObjectDecl *newBuf = new ObjectDecl( bufNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0,
 						new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ),
-						true, false, std::list<Attribute*>{ new Attribute( std::string{"aligned"}, std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
+						true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
 					stmtsToAdd.push_back( new DeclStmt( noLabels, newBuf ) );
 
 					delete objectDecl->get_init();
-
-					objectDecl->set_init( new SingleInit( new NameExpr( bufName ) ) );
+					objectDecl->set_init( new SingleInit( new VariableExpr( newBuf ) ) );
 				}
 			}
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/GenPoly/GenPoly.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -336,10 +336,10 @@
 				assertf(bparam, "Aggregate parameters should be type expressions");
 
-				// xxx - might need to let VoidType be a wildcard here too; could have some voids 
+				// xxx - might need to let VoidType be a wildcard here too; could have some voids
 				// stuffed in for dtype-statics.
 				// if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;
 				if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;
 			}
-			
+
 			return true;
 		}
@@ -350,9 +350,9 @@
 		// polymorphic types always match
 		if ( aid == type_index{typeid(TypeInstType)} ) return true;
-		
+
 		type_index bid{ typeid(*b) };
 		// polymorphic types always match
 		if ( bid == type_index{typeid(TypeInstType)} ) return true;
-		
+
 		// can't match otherwise if different types
 		if ( aid != bid ) return false;
@@ -377,5 +377,5 @@
 				ConstantExpr *ad = dynamic_cast<ConstantExpr*>( aa->get_dimension() );
 				ConstantExpr *bd = dynamic_cast<ConstantExpr*>( ba->get_dimension() );
-				if ( ad && bd 
+				if ( ad && bd
 						&& ad->get_constant()->get_value() != bd->get_constant()->get_value() )
 					return false;
@@ -433,4 +433,5 @@
 
 	void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
+		// xxx - should this actually be insert?
 		tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
 	}
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/InitTweak/FixInit.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -127,5 +127,5 @@
 
 			// don't go into other functions
-			virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {}
+			virtual void visit( FunctionDecl * ) override {}
 
 		  protected:
@@ -913,5 +913,8 @@
 		// of the error.  See C++ Reference 6.6 Jump Statements for details.
 		void InsertDtors::handleGoto( BranchStmt * stmt ) {
-			assert( stmt->get_target() != "" && "BranchStmt missing a label" );
+			// can't do anything for computed goto
+			if ( stmt->computedTarget ) return;
+
+			assertf( stmt->get_target() != "", "BranchStmt missing a label: %s", toString( stmt ).c_str() );
 			// S_L = lvars = set of objects in scope at label definition
 			// S_G = curVars = set of objects in scope at goto statement
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/InitTweak/InitTweak.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -325,5 +325,5 @@
 			std::string name = getFunctionName( expr );
 			assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
-			assertf( ! expr->get_args().empty(), "Can't get called function from dereference with no arguments" );
+			assertf( ! expr->get_args().empty(), "Cannot get called function from dereference with no arguments" );
 			return getCalledFunction( expr->get_args().front() );
 		}
@@ -433,5 +433,5 @@
 			std::string name = getFunctionName( expr );
 			assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
-			assertf( ! expr->get_args().empty(), "Can't get function name from dereference with no arguments" );
+			assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
 			return funcName( expr->get_args().front() );
 		}
@@ -497,10 +497,7 @@
 		using Visitor::visit;
 
-		virtual void visit( __attribute((unused)) ApplicationExpr *applicationExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedExpr *untypedExpr ) { isConstExpr = false; }
-		virtual void visit( NameExpr *nameExpr ) {
-			// xxx - temporary hack, because 0 and 1 really should be constexprs, even though they technically aren't in Cforall today
-			if ( nameExpr->get_name() != "0" && nameExpr->get_name() != "1" ) isConstExpr = false;
-		}
+		virtual void visit( ApplicationExpr * ) { isConstExpr = false; }
+		virtual void visit( UntypedExpr * ) { isConstExpr = false; }
+		virtual void visit( NameExpr * ) { isConstExpr = false; }
 		// virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
 		virtual void visit( AddressExpr *addressExpr ) {
@@ -509,8 +506,7 @@
 			if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
 		}
-		virtual void visit( __attribute((unused)) LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) MemberExpr *memberExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) VariableExpr *variableExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; }
+		virtual void visit( MemberExpr * ) { isConstExpr = false; }
+		virtual void visit( VariableExpr * ) { isConstExpr = false; }
 		// these might be okay?
 		// virtual void visit( SizeofExpr *sizeofExpr );
@@ -523,11 +519,11 @@
 		// virtual void visit( LogicalExpr *logicalExpr );
 		// virtual void visit( ConditionalExpr *conditionalExpr );
-		virtual void visit( __attribute((unused)) TypeExpr *typeExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) AsmExpr *asmExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedValofExpr *valofExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) UntypedTupleExpr *tupleExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) TupleExpr *tupleExpr ) { isConstExpr = false; }
-		virtual void visit( __attribute((unused)) TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
+		virtual void visit( TypeExpr * ) { isConstExpr = false; }
+		virtual void visit( AsmExpr * ) { isConstExpr = false; }
+		virtual void visit( UntypedValofExpr * ) { isConstExpr = false; }
+		virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; }
+		virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; }
+		virtual void visit( TupleExpr * ) { isConstExpr = false; }
+		virtual void visit( TupleAssignExpr * ) { isConstExpr = false; }
 
 		bool isConstExpr;
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/ExpressionNode.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -7,9 +7,9 @@
 // ExpressionNode.cc --
 //
-// Author           : Rodolfo G. Esteves
+// Author           : Peter A. Buhr
 // Created On       : Sat May 16 13:17:07 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  2 11:12:00 2017
-// Update Count     : 568
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun Sep  3 22:21:21 2017
+// Update Count     : 639
 //
 
@@ -58,9 +58,21 @@
 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
 
-Expression * build_constantInteger( const std::string & str ) {
+static void sepNumeric( string & str, string & units ) {
+	string::size_type posn = str.find_first_of( "`" );
+	if ( posn != string::npos ) {
+		units = "?" + str.substr( posn );				// extract units
+		str.erase( posn );								// remove units
+	} // if
+} // sepNumeric
+
+Expression * build_constantInteger( string & str ) {
 	static const BasicType::Kind kind[2][3] = {
 		{ BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
 		{ BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
 	};
+
+	string units;										// units
+	sepNumeric( str, units );							// separate constant from units
+
 	bool dec = true, Unsigned = false;					// decimal, unsigned constant
 	int size;											// 0 => int, 1 => long, 2 => long long
@@ -69,4 +81,5 @@
 	Expression * ret;
 
+	// ROB: what do we do with units on 0 and 1?
 	// special constants
 	if ( str == "0" ) {
@@ -134,13 +147,20 @@
 	ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
   CLEANUP:
+	if ( units.length() != 0 ) {
+		ret = new UntypedExpr( new NameExpr( units ), { ret } );
+	} // if
+
 	delete &str;										// created by lex
 	return ret;
 } // build_constantInteger
 
-Expression * build_constantFloat( const std::string & str ) {
+Expression * build_constantFloat( string & str ) {
 	static const BasicType::Kind kind[2][3] = {
 		{ BasicType::Float, BasicType::Double, BasicType::LongDouble },
 		{ BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
 	};
+
+	string units;										// units
+	sepNumeric( str, units );							// separate constant from units
 
 	bool complx = false;								// real, complex
@@ -169,29 +189,67 @@
 
 	Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
+	if ( units.length() != 0 ) {
+		ret = new UntypedExpr( new NameExpr( units ), { ret } );
+	} // if
+
 	delete &str;										// created by lex
 	return ret;
 } // build_constantFloat
 
-Expression * build_constantChar( const std::string & str ) {
+static void sepString( string & str, string & units, char delimit ) {
+	string::size_type posn = str.find_last_of( delimit ) + 1;
+	if ( posn != str.length() ) {
+		units = "?" + str.substr( posn );				// extract units
+		str.erase( posn );								// remove units
+	} // if
+} // sepString
+
+Expression * build_constantChar( string & str ) {
+	string units;										// units
+	sepString( str, units, '\'' );						// separate constant from units
+
 	Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
+	if ( units.length() != 0 ) {
+		ret = new UntypedExpr( new NameExpr( units ), { ret } );
+	} // if
+
 	delete &str;										// created by lex
 	return ret;
 } // build_constantChar
 
-ConstantExpr * build_constantStr( const std::string & str ) {
-	// string should probably be a primitive type
-	ArrayType * at = new ArrayType( noQualifiers, new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
-								   new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
-								   false, false );
-	ConstantExpr * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
+Expression * build_constantStr( string & str ) {
+	string units;										// units
+	sepString( str, units, '"' );						// separate constant from units
+
+	BasicType::Kind strtype = BasicType::Char;			// default string type
+	switch ( str[0] ) {									// str has >= 2 characters, i.e, null string ""
+	  case 'u':
+		if ( str[1] == '8' ) break;						// utf-8 characters
+		strtype = BasicType::ShortUnsignedInt;
+		break;
+	  case 'U':
+		strtype = BasicType::UnsignedInt;
+		break;
+	  case 'L':
+		strtype = BasicType::SignedInt;
+		break;
+	} // switch
+	ArrayType * at = new ArrayType( noQualifiers, new BasicType( Type::Qualifiers( Type::Const ), strtype ),
+									new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
+									false, false );
+	Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
+	if ( units.length() != 0 ) {
+		ret = new UntypedExpr( new NameExpr( units ), { ret } );
+	} // if
+
 	delete &str;										// created by lex
 	return ret;
 } // build_constantStr
 
-Expression * build_field_name_FLOATINGconstant( const std::string & str ) {
+Expression * build_field_name_FLOATINGconstant( const string & str ) {
 	// str is of the form A.B -> separate at the . and return member expression
 	int a, b;
 	char dot;
-	std::stringstream ss( str );
+	stringstream ss( str );
 	ss >> a >> dot >> b;
 	UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
@@ -207,6 +265,6 @@
 		} else {
 			return new UntypedMemberExpr( fracts, fieldName );
-		}
-	}
+		} // if
+	} // if
 	return fieldName;
 } // make_field_name_fraction_constants
@@ -216,14 +274,14 @@
 } // build_field_name_fraction_constants
 
-Expression * build_field_name_REALFRACTIONconstant( const std::string & str ) {
+Expression * build_field_name_REALFRACTIONconstant( const string & str ) {
 	if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
-	Expression * ret = build_constantInteger( *new std::string( str.substr(1) ) );
+	Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
 	delete &str;
 	return ret;
 } // build_field_name_REALFRACTIONconstant
 
-Expression * build_field_name_REALDECIMALconstant( const std::string & str ) {
+Expression * build_field_name_REALDECIMALconstant( const string & str ) {
 	if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
-	Expression * ret = build_constantInteger( *new std::string( str.substr( 0, str.size()-1 ) ) );
+	Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
 	delete &str;
 	return ret;
@@ -236,5 +294,5 @@
 } // build_varref
 
-
+// TODO: get rid of this and OperKinds and reuse code from OperatorTable
 static const char * OperName[] = {						// must harmonize with OperKinds
 	// diadic
@@ -244,5 +302,5 @@
 	"?[?]", "...",
 	// monadic
-	"+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
+	"+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--",
 }; // OperName
 
@@ -307,5 +365,5 @@
 
 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
-	std::list< Expression * > args;
+	list< Expression * > args;
 	args.push_back( maybeMoveBuild< Expression >(expr_node) );
 	return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
@@ -313,11 +371,11 @@
 
 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
-	std::list< Expression * > args;
-	args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx
+	list< Expression * > args;
+	args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
 	return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
 } // build_unary_ptr
 
 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
-	std::list< Expression * > args;
+	list< Expression * > args;
 	args.push_back( maybeMoveBuild< Expression >(expr_node1) );
 	args.push_back( maybeMoveBuild< Expression >(expr_node2) );
@@ -326,5 +384,5 @@
 
 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
-	std::list< Expression * > args;
+	list< Expression * > args;
 	args.push_back( maybeMoveBuild< Expression >(expr_node1) );
 	args.push_back( maybeMoveBuild< Expression >(expr_node2) );
@@ -349,5 +407,5 @@
 
 Expression * build_tuple( ExpressionNode * expr_node ) {
-	std::list< Expression * > exprs;
+	list< Expression * > exprs;
 	buildMoveList( expr_node, exprs );
 	return new UntypedTupleExpr( exprs );;
@@ -355,5 +413,5 @@
 
 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
-	std::list< Expression * > args;
+	list< Expression * > args;
 	buildMoveList( expr_node, args );
 	return new UntypedExpr( maybeMoveBuild< Expression >(function), args, nullptr );
@@ -364,5 +422,5 @@
 } // build_range
 
-Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand ) {
+Expression * build_asmexpr( ExpressionNode * inout, Expression * constraint, ExpressionNode * operand ) {
 	return new AsmExpr( maybeMoveBuild< Expression >( inout ), constraint, maybeMoveBuild< Expression >(operand) );
 } // build_asmexpr
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/ParseNode.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:28:16 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 13:46:00 2017
-// Update Count     : 795
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun Sep  3 19:24:34 2017
+// Update Count     : 799
 //
 
@@ -154,5 +154,5 @@
 	Index, Range,
 	// monadic
-	UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
+	UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
 	Ctor, Dtor,
 }; // OperKinds
@@ -162,8 +162,8 @@
 };
 
-Expression * build_constantInteger( const std::string &str );
-Expression * build_constantFloat( const std::string &str );
-Expression * build_constantChar( const std::string &str );
-ConstantExpr * build_constantStr( const std::string &str );
+Expression * build_constantInteger( std::string &str );
+Expression * build_constantFloat( std::string &str );
+Expression * build_constantChar( std::string &str );
+Expression * build_constantStr( std::string &str );
 Expression * build_field_name_FLOATINGconstant( const std::string & str );
 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
@@ -197,5 +197,5 @@
 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
 Expression * build_range( ExpressionNode * low, ExpressionNode * high );
-Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand );
+Expression * build_asmexpr( ExpressionNode * inout, Expression * constraint, ExpressionNode * operand );
 Expression * build_valexpr( StatementNode * s );
 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
@@ -330,5 +330,5 @@
 	bool hasEllipsis;
 	LinkageSpec::Spec linkage;
-	ConstantExpr *asmName;
+	Expression *asmName;
 	std::list< Attribute * > attributes;
 	InitializerNode * initializer;
@@ -413,5 +413,5 @@
 Statement * build_finally( StatementNode * stmt );
 Statement * build_compound( StatementNode * first );
-Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
+Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/StatementNode.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 14:59:41 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 16:01:31 2017
-// Update Count     : 345
+// Last Modified On : Fri Sep  1 23:25:23 2017
+// Update Count     : 346
 //
 
@@ -99,7 +99,19 @@
 	} // if
 
-	Expression * cond = ctl->condition ? maybeMoveBuild< Expression >(ctl->condition) : new VariableExpr( dynamic_cast<DeclarationWithType *>( dynamic_cast<DeclStmt *>( init.back() )->decl ) );
+	Expression * cond = nullptr;
+	if ( ctl->condition ) {
+		// compare the provided condition against 0
+		cond =  notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
+	} else {
+		for ( Statement * stmt : init ) {
+			// build the && of all of the declared variables compared against 0
+			DeclStmt * declStmt = safe_dynamic_cast< DeclStmt * >( stmt );
+			DeclarationWithType * dwt = safe_dynamic_cast< DeclarationWithType * >( declStmt->decl );
+			Expression * nze = notZeroExpr( new VariableExpr( dwt ) );
+			cond = cond ? new LogicalExpr( cond, nze, true ) : nze;
+		}
+	}
 	delete ctl;
-	return new IfStmt( noLabels, notZeroExpr( cond ), thenb, elseb, init );
+	return new IfStmt( noLabels, cond, thenb, elseb, init );
 }
 
@@ -288,5 +300,5 @@
 }
 
-Statement *build_asmstmt( bool voltile, ConstantExpr *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) {
+Statement *build_asmstmt( bool voltile, Expression *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) {
 	std::list< Expression * > out, in;
 	std::list< ConstantExpr * > clob;
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/TypeData.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 15:12:51 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Aug 14 10:41:00 2017
-// Update Count     : 568
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri Sep  1 23:13:38 2017
+// Update Count     : 569
 //
 
@@ -814,5 +814,5 @@
 } // buildTypeof
 
-Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, ConstantExpr *asmName, Initializer * init, std::list< Attribute * > attributes ) {
+Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
 	if ( td->kind == TypeData::Function ) {
 		if ( td->function.idList ) {					// KR function ?
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/TypeData.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 15:18:36 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Aug 14 10:38:00 2017
-// Update Count     : 189
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri Sep  1 23:33:45 2017
+// Update Count     : 190
 //
 
@@ -118,5 +118,5 @@
 TupleType * buildTuple( const TypeData * );
 TypeofType * buildTypeof( const TypeData * );
-Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, ConstantExpr *asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
+Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
 FunctionType * buildFunction( const TypeData * );
 void buildKRFunction( const TypeData::Function_t & function );
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/lex.ll	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Tue Aug 22 22:43:39 2017
- * Update Count     : 558
+ * Last Modified On : Thu Aug 31 21:30:10 2017
+ * Update Count     : 598
  */
 
@@ -19,5 +19,5 @@
 
 %{
-// This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive have been
+// The lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive have been
 // performed and removed from the source. The only exceptions are preprocessor directives passed to the compiler (e.g.,
 // line-number directives) and C/C++ style comments, which are ignored.
@@ -25,6 +25,10 @@
 //**************************** Includes and Defines ****************************
 
+unsigned int column = 0;								// position of the end of the last token parsed
+#define YY_USER_ACTION column += yyleng;				// trigger before each matching rule's action
+
 #include <string>
 #include <cstdio>										// FILENAME_MAX
+using namespace std;
 
 #include "ParseNode.h"
@@ -32,13 +36,13 @@
 
 char *yyfilename;
-std::string *strtext;									// accumulate parts of character and string constant value
+string *strtext;										// accumulate parts of character and string constant value
 
 #define RETURN_LOCN(x)		yylval.tok.loc.file = yyfilename; yylval.tok.loc.line = yylineno; return( x )
-#define RETURN_VAL(x)		yylval.tok.str = new std::string( yytext ); RETURN_LOCN( x )
+#define RETURN_VAL(x)		yylval.tok.str = new string( yytext ); RETURN_LOCN( x )
 #define RETURN_CHAR(x)		yylval.tok.str = nullptr; RETURN_LOCN( x )
 #define RETURN_STR(x)		yylval.tok.str = strtext; RETURN_LOCN( x )
 
 #define WHITE_RETURN(x)		// do nothing
-#define NEWLINE_RETURN()	WHITE_RETURN( '\n' )
+#define NEWLINE_RETURN()	column = 0; WHITE_RETURN( '\n' )
 #define ASCIIOP_RETURN()	RETURN_CHAR( (int)yytext[0] ) // single character operator
 #define NAMEDOP_RETURN(x)	RETURN_CHAR( x )			// multichar operator, with a name
@@ -53,4 +57,12 @@
 	yyleng = 0;
 	for ( int i = 0; yytext[i] != '\0'; i += 1 ) {
+		if ( yytext[i] == '`' ) {
+			// copy user suffix
+			for ( ; yytext[i] != '\0'; i += 1 ) {
+				yytext[yyleng] = yytext[i];
+				yyleng += 1;
+			} // for
+			break;
+		} // if
 		if ( yytext[i] != '_' ) {
 			yytext[yyleng] = yytext[i];
@@ -77,31 +89,33 @@
 attr_identifier "@"{identifier}
 
+user_suffix_opt ("`"{identifier})?
+
 				// numeric constants, CFA: '_' in constant
 hex_quad {hex}("_"?{hex}){3}
-integer_suffix "_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?)))
+integer_suffix_opt ("_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?))))?
 
 octal_digits ({octal})|({octal}({octal}|"_")*{octal})
 octal_prefix "0""_"?
-octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix}?
+octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix_opt}{user_suffix_opt}
 
 nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
-decimal_constant {nonzero_digits}{integer_suffix}?
+decimal_constant {nonzero_digits}{integer_suffix_opt}{user_suffix_opt}
 
 hex_digits ({hex})|({hex}({hex}|"_")*{hex})
 hex_prefix "0"[xX]"_"?
-hex_constant {hex_prefix}{hex_digits}{integer_suffix}?
-
+hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt}{user_suffix_opt}
+
+				// GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
+floating_suffix_opt ("_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL"))?
 decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
-real_decimal {decimal_digits}"."{exponent}?{floating_suffix}?
-real_fraction "."{decimal_digits}{exponent}?{floating_suffix}?
+real_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}{user_suffix_opt}
+real_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}{user_suffix_opt}
 real_constant {decimal_digits}{real_fraction}
 exponent "_"?[eE]"_"?[+-]?{decimal_digits}
-				// GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
-floating_suffix "_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL")
-floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix}?
+floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix_opt}{user_suffix_opt}
 
 binary_exponent "_"?[pP]"_"?[+-]?{decimal_digits}
 hex_fractional_constant ({hex_digits}?"."{hex_digits})|({hex_digits}".")
-hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix}?
+hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix_opt}
 
 				// character escape sequence, GCC: \e => esc character
@@ -154,5 +168,5 @@
 		memcpy( &filename, begin_string + 1, length );	// copy file name from yytext
 		filename[ length ] = '\0';						// terminate string with sentinel
-		//std::cout << "file " << filename << " line " << lineno << std::endl;
+		//cout << "file " << filename << " line " << lineno << endl;
 		yylineno = lineno;
 		yyfilename = filename;
@@ -302,13 +316,13 @@
 
 				/* character constant, allows empty value */
-({cwide_prefix}[_]?)?['] { BEGIN QUOTE; rm_underscore(); strtext = new std::string( yytext, yyleng ); }
+({cwide_prefix}[_]?)?['] { BEGIN QUOTE; rm_underscore(); strtext = new string( yytext, yyleng ); }
 <QUOTE>[^'\\\n]* { strtext->append( yytext, yyleng ); }
-<QUOTE>['\n]	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
+<QUOTE>['\n]{user_suffix_opt}	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
 				/* ' stop highlighting */
 
 				/* string constant */
-({swide_prefix}[_]?)?["] { BEGIN STRING; rm_underscore(); strtext = new std::string( yytext, yyleng ); }
+({swide_prefix}[_]?)?["] { BEGIN STRING; rm_underscore(); strtext = new string( yytext, yyleng ); }
 <STRING>[^"\\\n]* { strtext->append( yytext, yyleng ); }
-<STRING>["\n]	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
+<STRING>["\n]{user_suffix_opt}	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
 				/* " stop highlighting */
 
@@ -383,5 +397,6 @@
 {op_unary}"?"	{ IDENTIFIER_RETURN(); }				// unary
 "?"({op_unary_pre_post}|"()"|"[?]"|"{}") { IDENTIFIER_RETURN(); }
-"^?{}" { IDENTIFIER_RETURN(); }
+"^?{}"			{ IDENTIFIER_RETURN(); }
+"?`"{identifier} { IDENTIFIER_RETURN(); }				// unit operator
 "?"{op_binary_over}"?"	{ IDENTIFIER_RETURN(); }		// binary
 	/*
@@ -422,8 +437,14 @@
 }
 
-				/* unknown characters */
-.				{ printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno); }
+				/* unknown character */
+.				{ yyerror( "unknown character" ); }
 
 %%
+// ----end of lexer----
+
+void yyerror( const char * errmsg ) {
+	cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
+		 << ": " << SemanticError::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
+}
 
 // Local Variables: //
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/Parser/parser.yy	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Aug 26 17:50:19 2017
-// Update Count     : 2712
+// Last Modified On : Sun Sep  3 20:43:19 2017
+// Update Count     : 2742
 //
 
@@ -48,9 +48,11 @@
 #include <cstdio>
 #include <stack>
+using namespace std;
+
 #include "ParseNode.h"
 #include "TypedefTable.h"
 #include "TypeData.h"
 #include "LinkageSpec.h"
-using namespace std;
+#include "Common/SemanticError.h"						// error_str
 
 extern DeclarationNode * parseTree;
@@ -98,5 +100,5 @@
 	StatementNode * sn;
 	WaitForStmt * wfs;
-	ConstantExpr * constant;
+	Expression * constant;
 	IfCtl * ifctl;
 	ForCtl * fctl;
@@ -534,4 +536,7 @@
 				$$ = new ExpressionNode( build_unary_val( $1, $2 ) );
 				break;
+			  case OperKinds::And:
+				$$ = new ExpressionNode( new AddressExpr( build_addressOf( $2 ) ) );
+				break;
 			  default:
 				assert( false );
@@ -560,6 +565,4 @@
 	| ATTR_IDENTIFIER '(' type ')'
 		{ $$ = new ExpressionNode( build_attrtype( build_varref( $1 ), $3 ) ); }
-//	| ANDAND IDENTIFIER									// GCC, address of label
-//		{ $$ = new ExpressionNode( new OperatorNode( OperKinds::LabelAddress ), new ExpressionNode( build_varref( $2 ) ); }
 	;
 
@@ -3133,14 +3136,4 @@
 // ----end of grammar----
 
-extern char *yytext;
-
-void yyerror( const char * ) {
-	cout << "Error ";
-	if ( yyfilename ) {
-		cout << "in file " << yyfilename << " ";
-	} // if
-	cout << "at line " << yylineno << " reading token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << "\"" << endl;
-}
-
 // Local Variables: //
 // mode: c++ //
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:52:08 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Jul 26 11:33:00 2017
-// Update Count     : 31
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 13:47:24 2017
+// Update Count     : 32
 //
 
@@ -195,5 +195,5 @@
 				AltList winners;
 				findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
-				stream << "Can't choose between " << winners.size() << " alternatives for expression ";
+				stream << "Cannot choose between " << winners.size() << " alternatives for expression ";
 				expr->print( stream );
 				stream << "Alternatives are:";
@@ -698,16 +698,4 @@
 
 	void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
-		{
-			std::string fname = InitTweak::getFunctionName( untypedExpr );
-			if ( fname == "&&" ) {
-				VoidType v = Type::Qualifiers();		// resolve to type void *
-				PointerType pt( Type::Qualifiers(), v.clone() );
-				UntypedExpr *vexpr = untypedExpr->clone();
-				vexpr->set_result( pt.clone() );
-				alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
-				return;
-			}
-		}
-
 		AlternativeFinder funcFinder( indexer, env );
 		funcFinder.findWithAdjustment( untypedExpr->get_function() );
@@ -749,18 +737,20 @@
 				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
 					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
-						referenceToRvalueConversion( func->expr );
+						Alternative newFunc( *func );
+						referenceToRvalueConversion( newFunc.expr );
 						for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
 							// XXX
 							//Designators::check_alternative( function, *actualAlt );
-							makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
+							makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
 						}
 					}
 				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
-					referenceToRvalueConversion( func->expr );
 					EqvClass eqvClass;
 					if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
 						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
+							Alternative newFunc( *func );
+							referenceToRvalueConversion( newFunc.expr );
 							for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
-								makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
+								makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
 							} // for
 						} // if
@@ -773,10 +763,11 @@
 					if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
 						if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
-							referenceToRvalueConversion( funcOp->expr );
+							Alternative newFunc( *funcOp );
+							referenceToRvalueConversion( newFunc.expr );
 							for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
 								AltList currentAlt;
 								currentAlt.push_back( *func );
 								currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
-								makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
+								makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) );
 							} // for
 						} // if
@@ -853,4 +844,8 @@
 			} // if
 		} // for
+	}
+
+	void AlternativeFinder::visit( LabelAddressExpr * expr ) {
+		alternatives.push_back( Alternative( expr->clone(), env, Cost::zero) );
 	}
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/ResolvExpr/AlternativeFinder.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -54,4 +54,5 @@
 		virtual void visit( UntypedExpr *untypedExpr );
 		virtual void visit( AddressExpr *addressExpr );
+		virtual void visit( LabelAddressExpr *labelExpr );
 		virtual void visit( CastExpr *castExpr );
 		virtual void visit( VirtualCastExpr *castExpr );
Index: src/ResolvExpr/RenameVars.cc
===================================================================
--- src/ResolvExpr/RenameVars.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/ResolvExpr/RenameVars.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -88,5 +88,4 @@
 		typeBefore( aggregateUseType );
 		acceptAll( aggregateUseType->get_parameters(), *this );
-		acceptAll( aggregateUseType->get_members(), *this );
 		typeAfter( aggregateUseType );
 	}
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -25,53 +25,4 @@
 
 namespace ResolvExpr {
-	// adding this comparison operator significantly improves assertion resolution run time for
-	// some cases. The current resolution algorithm's speed partially depends on the order of
-	// assertions. Assertions which have fewer possible matches should appear before
-	// assertions which have more possible matches. This seems to imply that this could
-	// be further improved by providing an indexer as an additional argument and ordering based
-	// on the number of matches of the same kind (object, function) for the names of the
-	// declarations.
-	//
-	// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
-	bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {
-			// Objects are always less than functions
-			if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {
-				if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {
-					// objects are ordered by name then type pointer, in that order
-					int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );
-					return cmp < 0 ||
-						( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );
-				} else {
-					return true;
-				}
-			} else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {
-				if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {
-					// functions are ordered by name, # parameters, # returnVals, type pointer in that order
-					FunctionType * ftype1 = funcDecl1->get_functionType();
-					FunctionType * ftype2 = funcDecl2->get_functionType();
-					int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();
-					int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();
-					if ( numThings1 < numThings2 ) return true;
-					if ( numThings1 > numThings2 ) return false;
-
-					// if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;
-					// else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;
-					// // same number of parameters
-					// if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;
-					// else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;
-					// same number of return vals
-					// int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );
-					// if ( cmp < 0 ) return true;
-					// else if ( cmp > 0 ) return false;
-					// // same name
-					return ftype1 < ftype2;
-				} else {
-					return false;
-				}
-			} else {
-				assert( false );
-			}
-		}
-
 	void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
 		for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/ResolvExpr/TypeEnvironment.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -28,6 +28,19 @@
 
 namespace ResolvExpr {
+	// adding this comparison operator significantly improves assertion resolution run time for
+	// some cases. The current resolution algorithm's speed partially depends on the order of
+	// assertions. Assertions which have fewer possible matches should appear before
+	// assertions which have more possible matches. This seems to imply that this could
+	// be further improved by providing an indexer as an additional argument and ordering based
+	// on the number of matches of the same kind (object, function) for the names of the
+	// declarations.
+	//
+	// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
 	struct AssertCompare {
-		bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const;
+		bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {
+			int cmp = d1->get_name().compare( d2->get_name() );
+			return cmp < 0 ||
+				( cmp == 0 && d1->get_type() < d2->get_type() );
+		}
 	};
 	struct AssertionSetValue {
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SymTab/Indexer.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -398,5 +398,4 @@
 	void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
 		acceptNewScope( labAddressExpr->get_result(), *this );
-		maybeAccept( labAddressExpr->get_arg(), *this );
 	}
 
@@ -554,7 +553,6 @@
 
 
-	void Indexer::visit( TraitInstType *contextInst ) {
-		acceptAll( contextInst->get_parameters(), *this );
-		acceptAll( contextInst->get_members(), *this );
+	void Indexer::visit( TraitInstType *traitInst ) {
+		acceptAll( traitInst->get_parameters(), *this );
 	}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SymTab/Validate.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:50:04 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Tus Aug  8 13:27:00 2017
-// Update Count     : 358
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 13:47:23 2017
+// Update Count     : 359
 //
 
@@ -127,13 +127,17 @@
 	  public:
 		LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
-  		using Parent::visit;
+		using Parent::visit;
+		void visit( TypeInstType *typeInst ) final;
+
 		void visit( EnumInstType *enumInst ) final;
 		void visit( StructInstType *structInst ) final;
 		void visit( UnionInstType *unionInst ) final;
-		void visit( TraitInstType *contextInst ) final;
+		void visit( TraitInstType *traitInst ) final;
+
 		void visit( EnumDecl *enumDecl ) final;
 		void visit( StructDecl *structDecl ) final;
 		void visit( UnionDecl *unionDecl ) final;
-		void visit( TypeInstType *typeInst ) final;
+		void visit( TraitDecl * traitDecl ) final;
+
 	  private:
 		const Indexer *indexer;
@@ -240,4 +244,10 @@
 	};
 
+	struct LabelAddressFixer final : public WithGuards {
+		std::set< Label > labels;
+
+		void premutate( FunctionDecl * funcDecl );
+		Expression * postmutate( AddressExpr * addrExpr );
+	};
 
 	FunctionDecl * dereferenceOperator = nullptr;
@@ -253,4 +263,5 @@
 		PassVisitor<ValidateGenericParameters> genericParams;
 		PassVisitor<FindSpecialDeclarations> finder;
+		PassVisitor<LabelAddressFixer> labelAddrFixer;
 
 		EliminateTypedef::eliminateTypedef( translationUnit );
@@ -270,4 +281,5 @@
 		ArrayLength::computeLength( translationUnit );
 		acceptAll( translationUnit, finder );
+		mutateAll( translationUnit, labelAddrFixer );
 	}
 
@@ -287,19 +299,4 @@
 
 	HoistStruct::HoistStruct() : inStruct( false ) {
-	}
-
-	void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {
-		std::list< Declaration * >::iterator i = declList.begin();
-		while ( i != declList.end() ) {
-			std::list< Declaration * >::iterator next = i;
-			++next;
-			if ( pred( *i ) ) {
-				if ( doDelete ) {
-					delete *i;
-				} // if
-				declList.erase( i );
-			} // if
-			i = next;
-		} // while
 	}
 
@@ -453,39 +450,81 @@
 	}
 
-	void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
+	template< typename Decl >
+	void normalizeAssertions( std::list< Decl * > & assertions ) {
+		// ensure no duplicate trait members after the clone
+		auto pred = [](Decl * d1, Decl * d2) {
+			// only care if they're equal
+			DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 );
+			DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
+			if ( dwt1 && dwt2 ) {
+				if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
+					// std::cerr << "=========== equal:" << std::endl;
+					// std::cerr << "d1: " << d1 << std::endl;
+					// std::cerr << "d2: " << d2 << std::endl;
+					return false;
+				}
+			}
+			return d1 < d2;
+		};
+		std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred );
+		// if ( unique_members.size() != assertions.size() ) {
+		// 	std::cerr << "============different" << std::endl;
+		// 	std::cerr << unique_members.size() << " " << assertions.size() << std::endl;
+		// }
+
+		std::list< Decl * > order;
+		order.splice( order.end(), assertions );
+		std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) {
+			return unique_members.count( decl );
+		});
+	}
+
+	// expand assertions from trait instance, performing the appropriate type variable substitutions
+	template< typename Iterator >
+	void expandAssertions( TraitInstType * inst, Iterator out ) {
+		assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
+		std::list< DeclarationWithType * > asserts;
+		for ( Declaration * decl : inst->baseTrait->members ) {
+			asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) );
+		}
+		// substitute trait decl parameters for instance parameters
+		applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out );
+	}
+
+	void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
+		Parent::visit( traitDecl );
+
+		if ( traitDecl->name == "sized" ) {
+			// "sized" is a special trait - flick the sized status on for the type variable
+			assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() );
+			TypeDecl * td = traitDecl->parameters.front();
+			td->set_sized( true );
+		}
+
+		// move assertions from type parameters into the body of the trait
+		for ( TypeDecl * td : traitDecl->parameters ) {
+			for ( DeclarationWithType * assert : td->assertions ) {
+				if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) {
+					expandAssertions( inst, back_inserter( traitDecl->members ) );
+				} else {
+					traitDecl->members.push_back( assert->clone() );
+				}
+			}
+			deleteAll( td->assertions );
+			td->assertions.clear();
+		} // for
+	}
+
+	void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
 		Parent::visit( traitInst );
-		if ( traitInst->get_name() == "sized" ) {
-			// "sized" is a special trait with no members - just flick the sized status on for the type variable
-			if ( traitInst->get_parameters().size() != 1 ) {
-				throw SemanticError( "incorrect number of trait parameters: ", traitInst );
-			}
-			TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
-			TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
-			TypeDecl * decl = inst->get_baseType();
-			decl->set_sized( true );
-			// since "sized" is special, the next few steps don't apply
-			return;
-		}
-
 		// handle other traits
-		TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
+		TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
 		if ( ! traitDecl ) {
-			throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
+			throw SemanticError( "use of undeclared trait " + traitInst->name );
 		} // if
 		if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
 			throw SemanticError( "incorrect number of trait parameters: ", traitInst );
 		} // if
-
-		for ( TypeDecl * td : traitDecl->get_parameters() ) {
-			for ( DeclarationWithType * assert : td->get_assertions() ) {
-				traitInst->get_members().push_back( assert->clone() );
-			} // for
-		} // for
-
-		// need to clone members of the trait for ownership purposes
-		std::list< Declaration * > members;
-		std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
-
-		applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
+		traitInst->baseTrait = traitDecl;
 
 		// need to carry over the 'sized' status of each decl in the instance
@@ -498,4 +537,5 @@
 			}
 		}
+		// normalizeAssertions( traitInst->members );
 	}
 
@@ -561,28 +601,26 @@
 	void forallFixer( Type * func ) {
 		for ( TypeDecl * type : func->get_forall() ) {
-			std::list< DeclarationWithType * > toBeDone, nextRound;
-			toBeDone.splice( toBeDone.end(), type->get_assertions() );
-			while ( ! toBeDone.empty() ) {
-				for ( DeclarationWithType * assertion : toBeDone ) {
-					if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
-						// expand trait instance into all of its members
-						for ( Declaration * member : traitInst->get_members() ) {
-							DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
-							nextRound.push_back( dwt->clone() );
-						}
-						delete traitInst;
-					} else {
-						// pass assertion through
-						FixFunction fixer;
-						assertion = assertion->acceptMutator( fixer );
-						if ( fixer.get_isVoid() ) {
-							throw SemanticError( "invalid type void in assertion of function ", func );
-						}
-						type->get_assertions().push_back( assertion );
-					} // if
-				} // for
-				toBeDone.clear();
-				toBeDone.splice( toBeDone.end(), nextRound );
-			} // while
+			std::list< DeclarationWithType * > asserts;
+			asserts.splice( asserts.end(), type->assertions );
+			// expand trait instances into their members
+			for ( DeclarationWithType * assertion : asserts ) {
+				if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
+					// expand trait instance into all of its members
+					expandAssertions( traitInst, back_inserter( type->assertions ) );
+					delete traitInst;
+				} else {
+					// pass other assertions through
+					type->assertions.push_back( assertion );
+				} // if
+			} // for
+			// apply FixFunction to every assertion to check for invalid void type
+			for ( DeclarationWithType *& assertion : type->assertions ) {
+				FixFunction fixer;
+				assertion = assertion->acceptMutator( fixer );
+				if ( fixer.get_isVoid() ) {
+					throw SemanticError( "invalid type void in assertion of function ", func );
+				} // if
+			} // for
+			// normalizeAssertions( type->assertions );
 		} // for
 	}
@@ -664,5 +702,5 @@
 		} else {
 			TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
-			assertf( base != typedeclNames.end(), "Can't find typedecl name %s", typeInst->get_name().c_str() );
+			assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->get_name().c_str() );
 			typeInst->set_baseType( base->second );
 		} // if
@@ -752,15 +790,13 @@
 		CompoundStmt *ret = Mutator::mutate( compoundStmt );
 		scopeLevel -= 1;
-		std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
-		while ( i != compoundStmt->get_kids().end() ) {
-			std::list< Statement * >::iterator next = i+1;
-			if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) {
+		// remove and delete decl stmts
+		filter( compoundStmt->kids, [](Statement * stmt) {
+			if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
 				if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
-					delete *i;
-					compoundStmt->get_kids().erase( i );
+					return true;
 				} // if
 			} // if
-			i = next;
-		} // while
+			return false;
+		}, true);
 		typedefNames.endScope();
 		return ret;
@@ -771,13 +807,5 @@
 	template<typename AggDecl>
 	AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
-		std::list<Declaration *>::iterator it = aggDecl->get_members().begin();
-		for ( ; it != aggDecl->get_members().end(); ) {
-			std::list< Declaration * >::iterator next = it+1;
-			if ( dynamic_cast< TypedefDecl * >( *it ) ) {
-				delete *it;
-				aggDecl->get_members().erase( it );
-			} // if
-			it = next;
-		}
+		filter( aggDecl->members, isTypedef, true );
 		return aggDecl;
 	}
@@ -957,4 +985,34 @@
 	}
 
+	struct LabelFinder {
+		std::set< Label > & labels;
+		LabelFinder( std::set< Label > & labels ) : labels( labels ) {}
+		void previsit( Statement * stmt ) {
+			for ( Label & l : stmt->labels ) {
+				labels.insert( l );
+			}
+		}
+	};
+
+	void LabelAddressFixer::premutate( FunctionDecl * funcDecl ) {
+		GuardValue( labels );
+		PassVisitor<LabelFinder> finder( labels );
+		funcDecl->accept( finder );
+	}
+
+	Expression * LabelAddressFixer::postmutate( AddressExpr * addrExpr ) {
+		// convert &&label into label address
+		if ( AddressExpr * inner = dynamic_cast< AddressExpr * >( addrExpr->arg ) ) {
+			if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( inner->arg ) ) {
+				if ( labels.count( nameExpr->name ) ) {
+					Label name = nameExpr->name;
+					delete addrExpr;
+					return new LabelAddressExpr( name );
+				}
+			}
+		}
+		return addrExpr;
+	}
+
 	void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
 		if ( ! dereferenceOperator ) {
Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/AddressExpr.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -70,4 +70,15 @@
 }
 
+LabelAddressExpr::LabelAddressExpr( const Label &arg ) : arg( arg ) {
+	// label address always has type void *
+	result = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
+}
+LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}
+LabelAddressExpr::~LabelAddressExpr() {}
+
+void LabelAddressExpr::print( std::ostream & os, int indent ) const {
+	os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Declaration.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Mon Aug 14 10:15:00 2017
-// Update Count     : 128
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun Sep  3 19:24:06 2017
+// Update Count     : 131
 //
 
@@ -82,5 +82,5 @@
 	int scopeLevel = 0;
 
-	ConstantExpr *asmName;
+	Expression *asmName;
 	std::list< Attribute * > attributes;
 
@@ -97,6 +97,6 @@
 	DeclarationWithType * set_scopeLevel( int newValue ) { scopeLevel = newValue; return this; }
 
-	ConstantExpr *get_asmName() const { return asmName; }
-	DeclarationWithType * set_asmName( ConstantExpr *newValue ) { asmName = newValue; return this; }
+	Expression *get_asmName() const { return asmName; }
+	DeclarationWithType * set_asmName( Expression *newValue ) { asmName = newValue; return this; }
 
 	std::list< Attribute * >& get_attributes() { return attributes; }
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Expression.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -9,8 +9,9 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Aug  8 11:54:00 2017
-// Update Count     : 44
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun Sep  3 19:23:46 2017
+// Update Count     : 48
 //
+
 #pragma once
 
@@ -24,4 +25,5 @@
 #include "Constant.h"             // for Constant
 #include "Initializer.h"          // for Designation (ptr only), Initializer
+#include "Label.h"                // for Label
 #include "Mutator.h"              // for Mutator
 #include "SynTree.h"              // for UniqueId
@@ -171,15 +173,13 @@
 };
 
-// xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack
+// GCC &&label
+// https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html
 class LabelAddressExpr : public Expression {
   public:
-	Expression * arg;
-
-	LabelAddressExpr( Expression * arg );
+	Label arg;
+
+	LabelAddressExpr( const Label &arg );
 	LabelAddressExpr( const LabelAddressExpr & other );
 	virtual ~LabelAddressExpr();
-
-	Expression * get_arg() const { return arg; }
-	void set_arg(Expression * newValue ) { arg = newValue; }
 
 	virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
@@ -538,8 +538,8 @@
   public:
 	Expression * inout;
-	ConstantExpr * constraint;
+	Expression * constraint;
 	Expression * operand;
 
-	AsmExpr( Expression * inout, ConstantExpr * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
+	AsmExpr( Expression * inout, Expression * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
 	AsmExpr( const AsmExpr & other );
 	virtual ~AsmExpr() { delete inout; delete constraint; delete operand; };
@@ -548,6 +548,6 @@
 	void set_inout( Expression * newValue ) { inout = newValue; }
 
-	ConstantExpr * get_constraint() const { return constraint; }
-	void set_constraint( ConstantExpr * newValue ) { constraint = newValue; }
+	Expression * get_constraint() const { return constraint; }
+	void set_constraint( Expression * newValue ) { constraint = newValue; }
 
 	Expression * get_operand() const { return operand; }
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Mutator.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -246,5 +246,4 @@
 	labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
 	labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
-	labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) );
 	return labelAddressExpr;
 }
@@ -538,5 +537,4 @@
 Type * Mutator::mutate( TraitInstType *aggregateUseType ) {
 	handleReferenceToType( aggregateUseType );
-	mutateAll( aggregateUseType->get_members(), *this );
 	return aggregateUseType;
 }
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/ReferenceToType.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -132,10 +132,10 @@
 std::string TraitInstType::typeString() const { return "trait"; }
 
-TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
-	cloneAll( other.members, members );
+TraitInstType::TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes ) : Parent( tq, baseTrait->name, attributes ), baseTrait( baseTrait ) {}
+
+TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ), baseTrait( other.baseTrait ) {
 }
 
 TraitInstType::~TraitInstType() {
-	deleteAll( members );
 }
 
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Statement.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 16:17:20 2017
-// Update Count     : 67
+// Last Modified On : Sun Sep  3 20:46:44 2017
+// Update Count     : 68
 //
 
@@ -52,5 +52,5 @@
 
 
-AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, ConstantExpr *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
+AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
 
 AsmStmt::AsmStmt( const AsmStmt & other ) : Statement( other ), voltile( other.voltile ), instruction( maybeClone( other.instruction ) ), gotolabels( other.gotolabels ) {
@@ -89,18 +89,23 @@
 
 BranchStmt::BranchStmt( std::list<Label> labels, Label target, Type type ) throw ( SemanticError ) :
-	Statement( labels ), originalTarget( target ), target( target ), computedTarget( NULL ), type( type ) {
+	Statement( labels ), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) {
 	//actually this is a syntactic error signaled by the parser
-	if ( type == BranchStmt::Goto && target.empty() )
+	if ( type == BranchStmt::Goto && target.empty() ) {
 		throw SemanticError("goto without target");
+	}
 }
 
 BranchStmt::BranchStmt( std::list<Label> labels, Expression *computedTarget, Type type ) throw ( SemanticError ) :
 	Statement( labels ), computedTarget( computedTarget ), type( type ) {
-	if ( type != BranchStmt::Goto || computedTarget == 0 )
+	if ( type != BranchStmt::Goto || computedTarget == nullptr ) {
 		throw SemanticError("Computed target not valid in branch statement");
+	}
 }
 
 void BranchStmt::print( std::ostream &os, int indent ) const {
 	os << string( indent, ' ' ) << "Branch (" << brType[type] << ")" << endl ;
+	if ( target != "" ) os << string( indent+2, ' ' ) << "with target: " << target << endl;
+	if ( originalTarget != "" ) os << string( indent+2, ' ' ) << "with original target: " << originalTarget << endl;
+	if ( computedTarget != nullptr ) os << string( indent+2, ' ' ) << "with computed target: " << computedTarget << endl;
 }
 
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Statement.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 15:37:53 2017
-// Update Count     : 72
+// Last Modified On : Sun Sep  3 20:46:46 2017
+// Update Count     : 77
 //
 
@@ -98,10 +98,10 @@
   public:
 	bool voltile;
-	ConstantExpr *instruction;
+	Expression *instruction;
 	std::list<Expression *> output, input;
 	std::list<ConstantExpr *> clobber;
 	std::list<Label> gotolabels;
 
-	AsmStmt( std::list<Label> labels, bool voltile, ConstantExpr *instruction, std::list<Expression *> input, std::list<Expression *> output, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
+	AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
 	AsmStmt( const AsmStmt &other );
 	virtual ~AsmStmt();
@@ -109,19 +109,19 @@
 	bool get_voltile() { return voltile; }
 	void set_voltile( bool newValue ) { voltile = newValue; }
-	ConstantExpr *get_instruction() { return instruction; }
-	void set_instruction( ConstantExpr *newValue ) { instruction = newValue; }
-	std::list<Expression *> &get_output() { return output; }
-	void set_output( const std::list<Expression *> &newValue ) { output = newValue; }
-	std::list<Expression *> &get_input() { return input; }
+	Expression * get_instruction() { return instruction; }
+	void set_instruction( Expression * newValue ) { instruction = newValue; }
+	std::list<Expression *> & get_output() { return output; }
+	void set_output( const std::list<Expression *> & newValue ) { output = newValue; }
+	std::list<Expression *> & get_input() { return input; }
 	void set_input( const std::list<Expression *> &newValue ) { input = newValue; }
-	std::list<ConstantExpr *> &get_clobber() { return clobber; }
+	std::list<ConstantExpr *> & get_clobber() { return clobber; }
 	void set_clobber( const std::list<ConstantExpr *> &newValue ) { clobber = newValue; }
-	std::list<Label> &get_gotolabels() { return gotolabels; }
+	std::list<Label> & get_gotolabels() { return gotolabels; }
 	void set_gotolabels( const std::list<Label> &newValue ) { gotolabels = newValue; }
 
-	virtual AsmStmt *clone() const { return new AsmStmt( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
+	virtual void accept( Visitor & v ) { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const;
 };
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Type.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -471,13 +471,12 @@
 	typedef ReferenceToType Parent;
   public:
-	// this member is filled in by the validate pass, which instantiates the members of the correponding
-	// aggregate with the actual type parameters specified for this use of the context
-	std::list< Declaration* > members;
-
-	TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
+	// this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree,
+	// where the trait used in this type is actually defined
+	TraitDecl * baseTrait = nullptr;
+
+	TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {}
+	TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 	TraitInstType( const TraitInstType & other );
 	~TraitInstType();
-
-	std::list< Declaration* >& get_members() { return members; }
 
 	virtual bool isComplete() const;
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/TypeSubstitution.h	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -177,5 +177,5 @@
 void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
 	TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
-	for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) {
+	for ( auto i = memberBegin; i != memberEnd; ++i ) {
 		sub.apply( *i );
 		*out++ = *i;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/SynTree/Visitor.cc	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -205,5 +205,4 @@
 void Visitor::visit( LabelAddressExpr *labAddressExpr ) {
 	maybeAccept( labAddressExpr->get_result(), *this );
-	maybeAccept( labAddressExpr->get_arg(), *this );
 }
 
@@ -429,5 +428,4 @@
 void Visitor::visit( TraitInstType *aggregateUseType ) {
 	handleReferenceToType( static_cast< ReferenceToType * >( aggregateUseType ) );
-	acceptAll( aggregateUseType->get_members(), *this );
 }
 
Index: src/benchmark/Makefile.am
===================================================================
--- src/benchmark/Makefile.am	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/benchmark/Makefile.am	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -31,33 +31,41 @@
 
 ctxswitch-coroutine$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 CorCtxSwitch.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 ctxswitch-thread$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 ThrdCtxSwitch.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 sched-int$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 monitor$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 Monitor.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 csv-data$(EXEEXT):
-	@${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
+	@${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=50000000 csv-data.c
 	@./a.out
 	@rm -f ./a.out
Index: src/benchmark/Makefile.in
===================================================================
--- src/benchmark/Makefile.in	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/benchmark/Makefile.in	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -581,33 +581,41 @@
 
 ctxswitch-coroutine$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 CorCtxSwitch.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 CorCtxSwitch.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 ctxswitch-thread$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 ThrdCtxSwitch.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 ThrdCtxSwitch.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 sched-int$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 SchedInt.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 monitor$(EXEEXT):
-	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
-	@for number in 1 2 3 4 5 6 7 8 9 10; do \
-                ./a.out ; \
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=50000000 Monitor.c
+	@rm -f .result.log
+	@for number in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do \
+                ./a.out | tee -a .result.log ; \
         done
-	@rm -f ./a.out
+	@./stat.py .result.log
+	@rm -f a.out .result.log
 
 csv-data$(EXEEXT):
-	@${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
+	@${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=50000000 csv-data.c
 	@./a.out
 	@rm -f ./a.out
Index: src/benchmark/stat.py
===================================================================
--- src/benchmark/stat.py	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/benchmark/stat.py	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+import sys
+import numpy
+
+if len(sys.argv) != 2 :
+	sys.exit("Expected file name as only argument")
+
+try:
+	with open(sys.argv[1]) as f:
+		content = f.readlines()
+		content = [x.strip() for x in content]
+		content = [int(x) for x in content]
+		content.remove(max(content))
+		content.remove(min(content))
+		print "median {0} avg {1} stddev {2}".format( numpy.median(content), numpy.mean(content), numpy.std(content) )
+
+
+except IOError as e:
+	sys.exit(e.strerror)
Index: src/libcfa/concurrency/coroutine
===================================================================
--- src/libcfa/concurrency/coroutine	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/libcfa/concurrency/coroutine	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,3 +1,2 @@
-//                              - *- Mode: CFA - *-
 //
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
@@ -11,6 +10,6 @@
 // Created On       : Mon Nov 28 12:27:26 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:57:17 2017
-// Update Count     : 2
+// Last Modified On : Wed Aug 30 07:58:29 2017
+// Update Count     : 3
 //
 
Index: src/libcfa/gmp
===================================================================
--- src/libcfa/gmp	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/libcfa/gmp	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
 // Created On       : Tue Apr 19 08:43:43 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 24 09:24:51 2017
-// Update Count     : 16
+// Last Modified On : Mon Sep  4 09:54:33 2017
+// Update Count     : 20
 //
 
@@ -32,4 +32,9 @@
 static inline void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
 static inline void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
+
+// literal
+static inline Int ?`mp( signed long int init ) { return (Int){ init }; }
+static inline Int ?`mp( unsigned long int init ) { return (Int){ init }; }
+static inline Int ?`mp( const char * init ) { return (Int){ init }; }
 
 // assignment
Index: src/prelude/prelude.cf
===================================================================
--- src/prelude/prelude.cf	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/prelude/prelude.cf	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,3 +1,2 @@
-//                               -*- Mode: C -*-
 //
 // Copyright (C) Glen Ditchfield 1994, 1999
@@ -8,6 +7,6 @@
 // Created On       : Sat Nov 29 07:23:41 2014
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul  5 18:04:40 2016
-// Update Count     : 92
+// Last Modified On : Wed Aug 30 07:56:07 2017
+// Update Count     : 93
 //
 
@@ -15,4 +14,14 @@
 
 // Section numbers from: http://plg.uwaterloo.ca/~cforall/refrat.pdf
+
+// ------------------------------------------------------------
+//
+// Section 6.7.11 Trait Declarations
+// Note: the sized trait is used in declarations later in this
+// file, so it must be out of order.
+//
+// ------------------------------------------------------------
+
+trait sized(dtype T) {};
 
 // ------------------------------------------------------------
Index: src/tests/.expect/64/gmp.txt
===================================================================
--- src/tests/.expect/64/gmp.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/64/gmp.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -5,4 +5,7 @@
 y:97
 y:12345678901234567890123456789
+y:200
+y:-400
+y:24691357802469135780246913578
 y:3
 y:-3
Index: src/tests/.expect/castError.txt
===================================================================
--- src/tests/.expect/castError.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/castError.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,3 +1,3 @@
-castError.c:7 error: Can't choose between 3 alternatives for expression Cast of:
+castError.c:7:1 error: Cannot choose between 3 alternatives for expression Cast of:
   Name: f
 
Index: src/tests/.expect/completeTypeError.txt
===================================================================
--- src/tests/.expect/completeTypeError.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/completeTypeError.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,3 +1,3 @@
-completeTypeError.c:34 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:34:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: *?
 ...to: 
@@ -5,5 +5,5 @@
 
 
-completeTypeError.c:36 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:36:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: baz
 ...to: 
@@ -11,5 +11,5 @@
 
 
-completeTypeError.c:37 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:37:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: quux
 ...to: 
@@ -17,5 +17,5 @@
 
 
-completeTypeError.c:58 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:58:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: baz
 ...to: 
@@ -23,5 +23,5 @@
 
 
-completeTypeError.c:59 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:59:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: quux
 ...to: 
@@ -29,5 +29,5 @@
 
 
-completeTypeError.c:60 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:60:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: *?
 ...to: 
@@ -35,5 +35,5 @@
 
 
-completeTypeError.c:72 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:72:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: baz
 ...to: 
Index: src/tests/.expect/declarationErrors.txt
===================================================================
--- src/tests/.expect/declarationErrors.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/declarationErrors.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,66 +1,66 @@
-declarationErrors.c:16 error: duplicate static in declaration of x1: static const volatile short int 
+declarationErrors.c:16:1 error: duplicate static in declaration of x1: static const volatile short int 
 
-declarationErrors.c:17 error: conflicting extern & static in declaration of x2: extern const volatile short int 
+declarationErrors.c:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int 
 
-declarationErrors.c:18 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int 
+declarationErrors.c:18:1 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int 
 
-declarationErrors.c:19 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
+declarationErrors.c:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
   with members 
    with body 
 
 
-declarationErrors.c:20 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
+declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
   with members 
    with body 
 
 
-declarationErrors.c:22 error: duplicate static in declaration of x6: static const volatile instance of type Int
+declarationErrors.c:22:1 error: duplicate static in declaration of x6: static const volatile instance of type Int
 
-declarationErrors.c:24 error: duplicate const in declaration of f01: static inline function
+declarationErrors.c:24:1 error: duplicate const in declaration of f01: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:25 error: duplicate volatile in declaration of f02: static inline function
+declarationErrors.c:25:1 error: duplicate volatile in declaration of f02: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:26 error: duplicate const in declaration of f03: static inline function
+declarationErrors.c:26:1 error: duplicate const in declaration of f03: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:27 error: duplicate volatile in declaration of f04: static inline function
+declarationErrors.c:27:1 error: duplicate volatile in declaration of f04: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:28 error: duplicate const in declaration of f05: static inline function
+declarationErrors.c:28:1 error: duplicate const in declaration of f05: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:29 error: duplicate volatile in declaration of f06: static inline function
+declarationErrors.c:29:1 error: duplicate volatile in declaration of f06: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:30 error: duplicate const in declaration of f07: static inline function
+declarationErrors.c:30:1 error: duplicate const in declaration of f07: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:31 error: duplicate const, duplicate volatile in declaration of f08: static inline function
+declarationErrors.c:31:1 error: duplicate const, duplicate volatile in declaration of f08: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:33 error: duplicate const, duplicate volatile in declaration of f09: static inline function
+declarationErrors.c:33:1 error: duplicate const, duplicate volatile in declaration of f09: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:34 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
+declarationErrors.c:34:1 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
   with no parameters 
   returning const restrict volatile _Atomic int 
Index: src/tests/.expect/dtor-early-exit-ERR1.txt
===================================================================
--- src/tests/.expect/dtor-early-exit-ERR1.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/dtor-early-exit-ERR1.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,1 +1,4 @@
-dtor-early-exit.c:142 error: jump to label 'L1' crosses initialization of y Branch (Goto)
+dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
+  with target: L1
+  with original target: L1
+
Index: src/tests/.expect/dtor-early-exit-ERR2.txt
===================================================================
--- src/tests/.expect/dtor-early-exit-ERR2.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/dtor-early-exit-ERR2.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,1 +1,4 @@
-dtor-early-exit.c:142 error: jump to label 'L2' crosses initialization of y Branch (Goto)
+dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
+  with target: L2
+  with original target: L2
+
Index: src/tests/.expect/function-operator.txt
===================================================================
--- src/tests/.expect/function-operator.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/tests/.expect/function-operator.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,32 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+Found 5 in x.
+Did not find 5 in y.
+0
+2
+4
+6
+8
+10
+12
+14
+16
+18
Index: src/tests/.expect/ifcond.txt
===================================================================
--- src/tests/.expect/ifcond.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/ifcond.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,3 +1,3 @@
 x != 0 correct
-x != 0 && y == 0 incorrect
+x != 0 && y != 0 correct
 x == y correct
Index: src/tests/.expect/memberCtors-ERR1.txt
===================================================================
--- src/tests/.expect/memberCtors-ERR1.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/memberCtors-ERR1.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,1 +1,1 @@
-memberCtors.c:71 error: in void ?{}(B &b), field a2 used before being constructed
+memberCtors.c:71:1 error: in void ?{}(B &b), field a2 used before being constructed
Index: src/tests/.expect/scopeErrors.txt
===================================================================
--- src/tests/.expect/scopeErrors.txt	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/.expect/scopeErrors.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,9 +1,10 @@
-scopeErrors.c:2 error: duplicate object definition for thisIsAnError: signed int
-scopeErrors.c:20 error: duplicate function definition for butThisIsAnError: function
+scopeErrors.c:2:1 error: duplicate object definition for thisIsAnError: signed int
+scopeErrors.c:20:1 error: duplicate function definition for butThisIsAnError: function
   with parameters
     double
-  returning
+  returning 
     _retval_butThisIsAnError:       Attribute with name: unused
 double
-  with body
+  with body 
     CompoundStmt
+
Index: src/tests/.expect/user_literals.txt
===================================================================
--- src/tests/.expect/user_literals.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/tests/.expect/user_literals.txt	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,6 @@
+11.0714285714286
+11.07225
+11.0714285714286
+11.0714285714286
+11.0714285714286
+22.0457142857143
Index: src/tests/div.c
===================================================================
--- src/tests/div.c	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/div.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,3 +1,2 @@
-//                               -*- Mode: C -*- 
 // 
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
@@ -11,6 +10,6 @@
 // Created On       : Tue Aug  8 16:28:43 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Aug  9 17:09:40 2017
-// Update Count     : 16
+// Last Modified On : Wed Aug 30 07:56:28 2017
+// Update Count     : 17
 // 
 
Index: src/tests/dtor-early-exit.c
===================================================================
--- src/tests/dtor-early-exit.c	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/dtor-early-exit.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -220,4 +220,22 @@
 }
 
+// TODO: implement __label__ and uncomment these lines
+void computedGoto() {
+  // __label__ bar;
+  void *ptr;
+  ptr = &&foo;
+  goto *ptr;
+  assert(false);
+foo: ;
+//   void f() {
+//     ptr = &&bar;
+//     goto *ptr;
+//     assert(false);
+//   }
+//   f();
+//   assert(false);
+// bar: ;
+}
+
 int main() {
 	sepDisable(sout);
@@ -229,4 +247,6 @@
 	sout | endl;
 	h();
+
+	computedGoto();
 }
 
Index: src/tests/function-operator.c
===================================================================
--- src/tests/function-operator.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/tests/function-operator.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,174 @@
+//
+// 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.
+//
+// function-operator.c --
+//
+// Author           : Rob Schluntz
+// Created On       : Fri Aug 25 15:21:11 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri Aug 25 15:31:29 2017
+// Update Count     : 2
+//
+
+#include <fstream>
+#include <stdlib>
+
+#define length(array) (sizeof((array))/sizeof((array)[0]))
+#define begin(array) (&array[0]) // there's currently a bug in passing an array to a polymorphic function, so ensure a pointer is passed instead
+#define end(array) (&array[length(array)])
+
+// STL-like Algorithms
+trait Assignable(dtype T, dtype U) { T ?=?(T &, U); };
+trait Copyable(dtype T) { void ?{}(T &, T); };
+trait Destructable(dtype T) { void ^?{}(T &); };
+
+trait Iterator(dtype iter | sized(iter) | Copyable(iter) | Destructable(iter), otype T) {
+	T & *?(iter);
+	iter ++?(iter &);
+	int ?!=?(iter, iter);
+};
+
+forall(otype Tin, dtype Input | Iterator(Input, Tin), otype Tout, dtype Output | Iterator(Output, Tout) | Assignable(Tout, Tin))
+Output copy(Input first, Input last, Output result) {
+  while (first != last) {
+    *result = *first;
+    ++result; ++first;
+  }
+  return result;
+}
+
+// test ?()(T *, ...) -- ?() with function call-by-pointer
+forall(otype Tin, dtype Input | Iterator(Input, Tin), otype Tout, dtype Output | Iterator(Output, Tout), otype FuncRet, dtype Func | { FuncRet ?()(Func *, Tin); } | Assignable(Tout, FuncRet))
+Output transform (Input first, Input last, Output result, Func * op) {
+  while (first != last) {
+    *result = op(*first);
+    ++result; ++first;
+  }
+  return result;
+}
+
+// test ?()(T, ...) -- ?() with function call-by-value
+forall(dtype Iter, otype T | Iterator(Iter, T), otype Pred | { int ?()(Pred, T); })
+Iter find_if (Iter first, Iter last, Pred pred) {
+  while (first != last) {
+    if (pred(*first)) return first;
+    ++first;
+  }
+  return last;
+}
+
+// test ?()(T, ...) -- ?() with function call-by-reference
+forall(otype Generator, otype GenRet | { GenRet ?()(Generator &); }, dtype Iter, otype T| Iterator(Iter, T) | Assignable(T, GenRet))
+void generate(Iter first, Iter last, Generator & gen) {
+  int i = 0;
+  while (first != last) {
+    *first = gen();
+    ++first;
+  }
+}
+
+// encapsulate a counter that increments by one every time it is called
+struct Counter { int c; };
+void ?{}(Counter & cnt) { cnt.c = 0; }
+int ?()(Counter & cnt) { return cnt.c++; }
+
+// TODO: abstract over os type with ostream trait; resolver is currently too slow for this to be reasonable, but it does work.
+struct os_wrapper {
+  ofstream * out;
+};
+
+// TODO: abstract over (os, T)
+os_wrapper ?=?(os_wrapper & wrapper, int x) {
+  wrapper.out | x | endl;
+  return wrapper;
+}
+
+struct ostream_iterator {
+  os_wrapper * out;
+};
+void ?{}(ostream_iterator & iter, ofstream * out) {
+  iter.out = new(out);
+}
+// no destructor, memory leak. This is necessary for this to work at the moment, since
+// *? requires its parameter by value and returns a reference.
+
+// implement Iterator
+os_wrapper & *?(ostream_iterator iter) {
+  return *iter.out;
+}
+ostream_iterator ++?(ostream_iterator & iter) {
+  // nothing to do
+  return iter;
+}
+int ?!=?(ostream_iterator i1, ostream_iterator i2) {
+  return i1.out->out != i2.out->out;
+}
+
+forall(otype T | { int ?==?(T, T); })
+struct Equals {
+	T val;
+};
+
+forall(otype T | { int ?==?(T, T); })
+int ?()(Equals(T) eq, T x) {
+	return eq.val == x;
+}
+
+forall(otype T | { T ?*?(T, T); })
+struct Multiply {
+	T val;
+};
+
+forall(otype T | { T ?*?(T, T); })
+T ?()(Multiply(T) * mult, T x) {
+	return mult->val * x;
+}
+
+// TODO: generalize to ttype return; doesn't work yet
+// like std::function
+forall(otype Return, ttype Args)
+struct function {
+  Return (*f)(Args);
+};
+// TODO: missing adapter in these functions
+// // value, reference, pointer operators
+// forall(otype Return, ttype Args) Return ?()(function(Return, Args) func, Args args) { return func.f(args); }
+// forall(otype Return, ttype Args) Return ?()(function(Return, Args) & func, Args args) { return func.f(args); }
+// forall(otype Return, ttype Args) Return ?()(function(Return, Args) * func, Args args) { return func->f(args); }
+
+int main() {
+	// generate for array fill
+	Counter c;
+	int x[10], y[10];
+	generate(begin(x), end(x), c);
+	generate(begin(y), end(y), c);
+
+	// copy for output
+	ostream_iterator out_iter = { sout };
+	copy(begin(x), end(x), out_iter);
+	copy(begin(y), end(y), out_iter);
+
+	// find_if for searching
+	Equals(int) is5 = { 5 };
+	if (find_if(begin(x), end(x), is5) != end(y)) {
+		printf("Found 5 in x.\n");
+	} else {
+		printf("Did not find 5 in x.\n");
+	}
+	if (find_if(begin(y), end(y), is5) != end(y)) {
+		printf("Found 5 in y.\n");
+	} else {
+		printf("Did not find 5 in y.\n");
+	}
+
+	Multiply(int) times2 = { 2 };
+	transform(begin(x), end(x), begin(x), &times2);
+	copy(begin(x), end(x), out_iter);
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// End: //
Index: src/tests/gmp.c
===================================================================
--- src/tests/gmp.c	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/gmp.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -10,6 +10,6 @@
 // Created On       : Tue Apr 19 08:55:51 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 25 12:50:01 2017
-// Update Count     : 544
+// Last Modified On : Mon Sep  4 09:51:18 2017
+// Update Count     : 550
 // 
 
@@ -29,4 +29,10 @@
 	sout | "y:" | y | endl;
 	y = "12345678901234567890123456789";
+	sout | "y:" | y | endl;
+	y = 100`mp + 100`mp;
+	sout | "y:" | y | endl;
+	y = -200u`mp + -200u`mp;
+	sout | "y:" | y | endl;
+	y = "12345678901234567890123456789"`mp + "12345678901234567890123456789"`mp;
 	sout | "y:" | y | endl;
 	y = si;
Index: src/tests/ifcond.c
===================================================================
--- src/tests/ifcond.c	(revision 871cdb4cbb92efed083345284bc13f2c3e0da057)
+++ src/tests/ifcond.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -1,19 +1,18 @@
-//                               -*- Mode: C -*- 
-// 
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
 //
 // The contents of this file are covered under the licence agreement in the
 // file "LICENCE" distributed with Cforall.
-// 
-// ifcond.c -- 
-// 
+//
+// ifcond.c --
+//
 // Author           : Peter A. Buhr
 // Created On       : Sat Aug 26 10:13:11 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Aug 26 11:13:00 2017
-// Update Count     : 11
-// 
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri Sep 01 15:22:19 2017
+// Update Count     : 14
+//
 
-#include<fstream>
+#include <fstream>
 
 int f( int r ) { return r; }
@@ -28,8 +27,10 @@
 	} // if
 
-	if ( int x = 4, y = 0 ) {							// FIXME && distribution
+	if ( int x = 4, y = 0 ) {
+		sout | "x != 0 && y != 0 incorrect" | endl;
+	} else if ( int x = 4, y = 1 ) {
 		sout | "x != 0 && y != 0 correct" | endl;
-    } else {
-		sout | "x != 0 && y == 0 incorrect" | endl;
+	} else {
+		sout | "x == 0 || y == 0 incorrect" | endl;
 	} // if
 
Index: src/tests/stdincludes.c
===================================================================
--- src/tests/stdincludes.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/tests/stdincludes.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,54 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// stdincludes.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Tue Aug 29 08:26:14 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Aug 30 07:56:39 2017
+// Update Count     : 5
+// 
+
+// C11 standard headers
+
+#include <assert.h>
+#include <complex.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fenv.h>
+#include <float.h>
+#include <inttypes.h>
+//#include <iso646.h>										// does not exist on linux
+#include <limits.h>
+#include <locale.h>
+#include <malloc.h>										// extra
+#include <math.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdalign.h>
+#include <stdarg.h>
+#include <stdatomic.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdnoreturn.h>
+#include <string.h>
+#include <tgmath.h>
+#include <time.h>
+#include <uchar.h>
+#include <unistd.h>										// extra
+#include <wchar.h>
+#include <wctype.h>
+
+int main() {}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa stdincludes.c" //
+// End: //
Index: src/tests/user_literals.c
===================================================================
--- src/tests/user_literals.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/tests/user_literals.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,52 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// user_literals.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Sep  6 21:40:50 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Sep  6 23:19:08 2017
+// Update Count     : 36
+// 
+
+#include <fstream>
+
+struct Weight {
+    double stones;
+};
+void ?{}( Weight & w ) { w.stones = 0; }	// constructors
+void ?{}( Weight & w, double w ) { w.stones = w; }
+
+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 }; } // user literals
+Weight ?`lb( double w ) { return (Weight){ w / 14.0 }; }
+Weight ?`kg( double w ) { return (Weight) { w * 0.1575}; }
+
+int main() {
+    Weight w, hw = { 14 };
+    w = 11`st + 1`lb;
+    sout | w | endl;
+    w = 70.3`kg;
+    sout | w | endl;
+    w = 155`lb;
+    sout | w | endl;
+    w = 0x9b`lb;		// hexadecimal weight
+    sout | w | endl;
+    w = 0233`lb;		// octal weight
+    sout | w | endl;
+    w = 5`st + 8`kg + 25`lb + hw;
+    sout | w | endl;
+}
+
+
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa user_literals.c" //
+// End: //
Index: src/tests/waitfor.c
===================================================================
--- src/tests/waitfor.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
+++ src/tests/waitfor.c	(revision b3f252a219989f7ab8f2f00efbcad32b69910b55)
@@ -0,0 +1,249 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// waitfor.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Aug 30 17:53:29 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Aug 30 17:55:17 2017
+// Update Count     : 2
+// 
+
+#include <stdbool.h>
+
+int fred() {
+	int x, z;
+
+	// test waitfor and when
+
+	waitfor( x );
+
+	waitfor( x ) {
+	}
+
+	waitfor( x, z ) {
+	}
+
+	when( true ) waitfor( x );
+
+	when( true ) waitfor( x ) {
+	}
+
+	waitfor( x );
+	or waitfor( y );
+
+	waitfor( x, z );
+	or waitfor( y );
+
+	when( true ) waitfor( x );
+	or when( true ) waitfor( y );
+
+	when( true ) waitfor( x, z );
+	or when( true ) waitfor( y );
+
+	waitfor( x ) {
+	} or waitfor( y ) {
+	}
+
+	waitfor( x, z ) {
+	} or waitfor( y ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) waitfor( y ) {
+	}
+
+	waitfor( x );
+	or waitfor( y ) {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) waitfor( y ) {
+	}
+
+	waitfor( x ) {
+	} or waitfor( y );
+
+	when( true ) waitfor( x ) {
+	} or when( true ) waitfor( y );
+
+	// test when, waitfor and else
+
+	waitfor( x );
+	or else;
+
+	when( true ) waitfor( x );
+	or else;
+
+	when( true ) waitfor( x, z );
+	or else;
+
+	waitfor( x ) {
+	} or else {
+	}
+
+	when( true ) waitfor( x ) {
+	} or else {
+	}
+
+	waitfor( x );
+	or else {
+	}
+
+	when( true ) waitfor( x );
+	or else {
+	}
+
+	when( true ) waitfor( x, z );
+	or else {
+	}
+
+	waitfor( x ) {
+	} or else;
+
+	when( true ) waitfor( x ) {
+	} or else;
+
+	waitfor( x );
+	or when( true ) else;
+
+	when( true ) waitfor( x );
+	or when( true ) else;
+
+	when( true ) waitfor( x, z );
+	or when( true ) else;
+
+	waitfor( x ) {
+	} or when( true ) else {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) else {
+	}
+
+	waitfor( x );
+	or when( true ) else {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) else {
+	}
+
+	when( true ) waitfor( x, z );
+	or when( true ) else {
+	}
+
+	waitfor( x ) {
+	} or when( true ) else;
+
+	when( true ) waitfor( x ) {
+	} or when( true ) else;
+
+	// test when, waitfor and timeout
+
+	waitfor( x );
+	or timeout( 3 );
+
+	waitfor( x, z );
+	or timeout( 3 );
+
+	when( true ) waitfor( x );
+	or timeout( 3 );
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x, z ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when ( true ) timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x, z ) {
+	} or when ( true ) timeout( 3 ) {
+	}
+
+	waitfor( x );
+	or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x );
+	or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) timeout( 3 ) {
+	}
+
+	waitfor( x ) {
+	} or timeout( 3 );
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 );
+
+	when( true ) waitfor( x ) {
+	} or when( true ) timeout( 3 );
+
+	// test when, waitfor, timeout and else
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	// test quasi-keywords "or" and "timeout"
+
+	int or, timeout;
+	waitfor( timeout, 7 ) 3;
+	waitfor( timeout, 7 ) 3; or waitfor( timeout, 7 ) 3;
+	when( or ) waitfor( or, ) { 4; } or timeout( 1 ) 3;
+	when( 3 ) waitfor( or, 2 ) 4; or else 4;
+	when( 3 ) waitfor( or, 3 ) 4; or when( or ) timeout( or ) 4; or when( or ) else timeout;
+	when( 3 ) waitfor( or, or ) 3; or when( or ) waitfor( or, timeout ) 4; or else 4;
+	when( 3 ) waitfor( or, or ) 3; or waitfor( or, 9 ) 4; or when( or ) timeout( timeout ) 4;
+	when( 3 ) waitfor( or, 3 ) 3; or waitfor( or, 7 ) or; or timeout( 1 ) or; or when( 3 ) else or;
+
+	// test else selection
+
+	if ( or > timeout ) waitfor( or ) 3;
+	else waitfor( timeout ) 4;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa waitfor.c" //
+// End: //
