Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/PassVisitor.impl.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -2277,40 +2277,149 @@
 }
 
-
+//--------------------------------------------------------------------------
+// TupleType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TupleType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->types, *this );
+	maybeAccept_impl( node->members, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+	maybeMutate_impl( node->types, *this );
+	maybeMutate_impl( node->members, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// TypeofType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( TypeofType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	assert( node->expr );
+	maybeAccept_impl( node->expr, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
+	MUTATE_START( node );
+
+	assert( node->expr );
+	maybeMutate_impl( node->expr, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// AttrType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( AttrType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	if ( node->isType ) {
+		assert( node->type );
+		maybeAccept_impl( node->type, *this );
+	} else {
+		assert( node->expr );
+		maybeAccept_impl( node->expr, *this );
+	} // if
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
+	MUTATE_START( node );
+
+	if ( node->isType ) {
+		assert( node->type );
+		maybeMutate_impl( node->type, *this );
+	} else {
+		assert( node->expr );
+		maybeMutate_impl( node->expr, *this );
+	} // if
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// VarArgsType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( VarArgsType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// ZeroType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ZeroType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// OneType
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( OneType * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( OneType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// Designation
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Designation * node ) {
 	VISIT_START( node );
 
-	maybeAccept_impl( node->get_designators(), *this );
+	maybeAccept_impl( node->designators, *this );
 
 	VISIT_END( node );
@@ -2321,5 +2430,5 @@
 	MUTATE_START( node );
 
-	maybeMutate_impl( node->get_designators(), *this );
+	maybeMutate_impl( node->designators, *this );
 
 	MUTATE_END( Designation, node );
@@ -2332,5 +2441,5 @@
 	VISIT_START( node );
 
-	visitExpression( node->get_value() );
+	visitExpression( node->value );
 
 	VISIT_END( node );
@@ -2341,91 +2450,109 @@
 	MUTATE_START( node );
 
-	node->set_value( mutateExpression( node->get_value() ) );
+	node->value = mutateExpression( node->value );
 
 	MUTATE_END( Initializer, node );
 }
 
+//--------------------------------------------------------------------------
+// ListInit
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ListInit * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->designations, *this );
+	maybeAccept_impl( node->initializers, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->designations, *this );
+	maybeMutate_impl( node->initializers, *this );
+
+	MUTATE_END( Initializer, node );
+}
+
+//--------------------------------------------------------------------------
+// ConstructorInit
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	maybeAccept_impl( node->ctor, *this );
+	maybeAccept_impl( node->dtor, *this );
+	maybeAccept_impl( node->init, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->ctor, *this );
+	maybeMutate_impl( node->dtor, *this );
+	maybeMutate_impl( node->init, *this );
+
+	MUTATE_END( Initializer, node );
+}
+
+//--------------------------------------------------------------------------
+// Subrange
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Subrange * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
+	MUTATE_START( node );
+
+	MUTATE_END( Subrange, node );
+}
+
+//--------------------------------------------------------------------------
+// Attribute
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Constant * node ) {
-	VISIT_BODY( node );
-}
-
+	VISIT_START( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
+	MUTATE_START( node );
+
+	MUTATE_END( Constant, node );
+}
+
+//--------------------------------------------------------------------------
+// Attribute
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( Attribute * node ) {
-	VISIT_BODY( node );
-}
-
-//---------------------------------------------------------------------------------------------------------------
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Type * PassVisitor< pass_type >::mutate( OneType * node ) {
-	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
-	MUTATE_BODY( Initializer, node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
-	MUTATE_BODY( Initializer, node );
-}
-
-template< typename pass_type >
-Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
-	MUTATE_BODY( Subrange, node );
-}
-
-template< typename pass_type >
-Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
-	MUTATE_BODY( Constant, node );
+	VISIT_START( node );
+
+	maybeAccept_impl( node->parameters, *this );
+
+	VISIT_END( node );
 }
 
 template< typename pass_type >
 Attribute * PassVisitor< pass_type >::mutate( Attribute * node  )  {
-	MUTATE_BODY( Attribute, node );
-}
-
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->parameters, *this );
+
+	MUTATE_END( Attribute, node );
+}
+
+//--------------------------------------------------------------------------
+// TypeSubstitution
 template< typename pass_type >
 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/SemanticError.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -14,4 +14,5 @@
 //
 
+#include <cstdarg>
 #include <cstdio>										// for fileno, stderr
 #include <unistd.h>										// for isatty
@@ -50,5 +51,26 @@
 }
 
-void SemanticWarningImpl( CodeLocation location, std::string msg ) {
+namespace {
+	// convert format string and arguments into a single string
+	std::string fmtToString(const char * fmt, va_list ap) {
+		int size = 128;
+		while ( true ) {
+			char buf[size];
+			va_list args;
+			va_copy( args, ap );
+			int n = vsnprintf(&buf[0], size, fmt, args);
+			va_end( args );
+			if ( n < size && n >= 0 ) return buf;
+			size *= 2;
+		}
+		assert( false );
+	}
+}
+
+void SemanticWarningImpl( CodeLocation location, Warning, const char * const fmt, ... ) {
+	va_list args;
+	va_start(args, fmt);
+	std::string msg = fmtToString( fmt, args );
+	va_end(args);
 	std::cerr << ErrorHelpers::bold() << location << ErrorHelpers::warning_str() << ErrorHelpers::reset_font() << msg << std::endl;
 }
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/SemanticError.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -37,8 +37,9 @@
 
 constexpr const char * const WarningFormats[] = {
-
+	"self assignment of expression: %s",
 };
 
 enum class Warning {
+	SelfAssignment,
 	NUMBER_OF_WARNINGS, //This MUST be the last warning
 };
@@ -49,5 +50,5 @@
 );
 
-#define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[id], __VA_ARGS__)
+#define SemanticWarning(loc, id, ...) SemanticWarningImpl(loc, id, WarningFormats[(int)id], __VA_ARGS__)
 
 void SemanticWarningImpl (CodeLocation loc, Warning warn, const char * const fmt, ...) __attribute__((format(printf, 3, 4)));
@@ -71,7 +72,4 @@
 }
 
-
-
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Common/utility.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -162,4 +162,6 @@
 }
 
+#define toCString( ... ) toString( __VA_ARGS__ ).c_str()
+
 // replace element of list with all elements of another list
 template< typename T >
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/GenPoly/Specialize.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -200,26 +200,4 @@
 	}
 
-	struct EnvTrimmer {
-		TypeSubstitution * env, * newEnv;
-		EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
-		void previsit( TypeDecl * tyDecl ) {
-			// transfer known bindings for seen type variables
-			if ( Type * t = env->lookup( tyDecl->name ) ) {
-				newEnv->add( tyDecl->name, t );
-			}
-		}
-	};
-
-	/// reduce environment to just the parts that are referenced in a given expression
-	TypeSubstitution * trimEnv( ApplicationExpr * expr, TypeSubstitution * env ) {
-		if ( env ) {
-			TypeSubstitution * newEnv = new TypeSubstitution();
-			PassVisitor<EnvTrimmer> trimmer( env, newEnv );
-			expr->accept( trimmer );
-			return newEnv;
-		}
-		return nullptr;
-	}
-
 	/// Generates a thunk that calls `actual` with type `funType` and returns its address
 	Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
@@ -265,5 +243,5 @@
 		}
 
-		appExpr->set_env( trimEnv( appExpr, env ) );
+		appExpr->env = TypeSubstitution::newFromExpr( appExpr, env );
 		if ( inferParams ) {
 			appExpr->get_inferParams() = *inferParams;
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/InitTweak/FixInit.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -68,4 +68,8 @@
 		typedef std::unordered_map< int, int > UnqCount;
 
+		struct SelfAssignChecker {
+			void previsit( ApplicationExpr * appExpr );
+		};
+
 		struct InsertImplicitCalls : public WithTypeSubstitution {
 			/// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
@@ -183,5 +187,5 @@
 		};
 
-		class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
+		class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithTypeSubstitution {
 		  public:
 			FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
@@ -235,4 +239,7 @@
 
 	void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
+		PassVisitor<SelfAssignChecker> checker;
+		acceptAll( translationUnit, checker );
+
 		// fixes ConstructorInit for global variables. should happen before fixInitializers.
 		InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
@@ -311,4 +318,81 @@
 		}
 
+		namespace {
+			// Relatively simple structural comparison for expressions, needed to determine
+			// if two expressions are "the same" (used to determine if self assignment occurs)
+			struct StructuralChecker {
+				Expression * stripCasts( Expression * expr ) {
+					// this might be too permissive. It's possible that only particular casts are relevant.
+					while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {
+						expr = cast->arg;
+					}
+					return expr;
+				}
+
+				void previsit( Expression * ) {
+					// anything else does not qualify
+					isSimilar = false;
+				}
+
+				template<typename T>
+				T * cast( Expression * node ) {
+					// all expressions need to ignore casts, so this bit has been factored out
+					return dynamic_cast< T * >( stripCasts( node ) );
+				}
+
+				// ignore casts
+				void previsit( CastExpr * ) {}
+
+				void previsit( MemberExpr * memExpr ) {
+					if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {
+						if ( otherMember->member == memExpr->member ) {
+							other = otherMember->aggregate;
+							return;
+						}
+					}
+					isSimilar = false;
+				}
+
+				void previsit( VariableExpr * varExpr ) {
+					if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {
+						if ( otherVar->var == varExpr->var ) {
+							return;
+						}
+					}
+					isSimilar = false;
+				}
+
+				void previsit( AddressExpr * ) {
+					if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {
+						other = addrExpr->arg;
+						return;
+					}
+					isSimilar = false;
+				}
+
+				Expression * other = nullptr;
+				bool isSimilar = true;
+			};
+
+			bool structurallySimilar( Expression * e1, Expression * e2 ) {
+				PassVisitor<StructuralChecker> checker;
+				checker.pass.other = e2;
+				e1->accept( checker );
+				return checker.pass.isSimilar;
+			}
+		}
+
+		void SelfAssignChecker::previsit( ApplicationExpr * appExpr ) {
+			DeclarationWithType * function = getFunction( appExpr );
+			if ( isAssignment( function ) ) {
+				if ( appExpr->args.size() == 2 ) {
+					// check for structural similarity (same variable use, ignore casts, etc. - but does not look too deeply, anything looking like a function is off limits)
+					if ( structurallySimilar( appExpr->args.front(), appExpr->args.back() ) ) {
+						SemanticWarning( appExpr->location, Warning::SelfAssignment, toCString( appExpr->args.front() ) );
+					}
+				}
+			}
+		}
+
 		Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
 			if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
@@ -364,9 +448,9 @@
 			ResolvExpr::findVoidExpression( resolved, indexer );
 			assert( resolved );
-			if ( resolved->get_env() ) {
+			if ( resolved->env ) {
 				// Extract useful information and discard new environments. Keeping them causes problems in PolyMutator passes.
-				env->add( *resolved->get_env() );
-				delete resolved->get_env();
-				resolved->set_env( nullptr );
+				env->add( *resolved->env );
+				delete resolved->env;
+				resolved->env = nullptr;
 			} // if
 			delete stmt;
@@ -550,4 +634,7 @@
 			// add destructors after current statement
 			for ( Expression * dtor : dtors ) {
+				// take relevant bindings from environment
+				assert( ! dtor->env );
+				dtor->env =  maybeClone( env );
 				stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
 			} // for
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Makefile.in	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -247,6 +247,4 @@
 	SynTree/driver_cfa_cpp-TypeDecl.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Initializer.$(OBJEXT) \
-	SynTree/driver_cfa_cpp-Visitor.$(OBJEXT) \
-	SynTree/driver_cfa_cpp-Mutator.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
@@ -527,9 +525,8 @@
 	SynTree/FunctionDecl.cc SynTree/AggregateDecl.cc \
 	SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
-	SynTree/Initializer.cc SynTree/Visitor.cc SynTree/Mutator.cc \
-	SynTree/TypeSubstitution.cc SynTree/Attribute.cc \
-	SynTree/VarExprReplacer.cc Tuples/TupleAssignment.cc \
-	Tuples/TupleExpansion.cc Tuples/Explode.cc \
-	Virtual/ExpandCasts.cc
+	SynTree/Initializer.cc SynTree/TypeSubstitution.cc \
+	SynTree/Attribute.cc SynTree/VarExprReplacer.cc \
+	Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
+	Tuples/Explode.cc Virtual/ExpandCasts.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -911,8 +908,4 @@
 SynTree/driver_cfa_cpp-Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
 	SynTree/$(DEPDIR)/$(am__dirstamp)
-SynTree/driver_cfa_cpp-Visitor.$(OBJEXT): SynTree/$(am__dirstamp) \
-	SynTree/$(DEPDIR)/$(am__dirstamp)
-SynTree/driver_cfa_cpp-Mutator.$(OBJEXT): SynTree/$(am__dirstamp) \
-	SynTree/$(DEPDIR)/$(am__dirstamp)
 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
 	SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
@@ -1053,5 +1046,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po@am__quote@
@@ -1069,5 +1061,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarExprReplacer.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@
@@ -2478,32 +2469,4 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Initializer.obj `if test -f 'SynTree/Initializer.cc'; then $(CYGPATH_W) 'SynTree/Initializer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Initializer.cc'; fi`
-
-SynTree/driver_cfa_cpp-Visitor.o: SynTree/Visitor.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Visitor.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo -c -o SynTree/driver_cfa_cpp-Visitor.o `test -f 'SynTree/Visitor.cc' || echo '$(srcdir)/'`SynTree/Visitor.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Visitor.cc' object='SynTree/driver_cfa_cpp-Visitor.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Visitor.o `test -f 'SynTree/Visitor.cc' || echo '$(srcdir)/'`SynTree/Visitor.cc
-
-SynTree/driver_cfa_cpp-Visitor.obj: SynTree/Visitor.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Visitor.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo -c -o SynTree/driver_cfa_cpp-Visitor.obj `if test -f 'SynTree/Visitor.cc'; then $(CYGPATH_W) 'SynTree/Visitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Visitor.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Visitor.cc' object='SynTree/driver_cfa_cpp-Visitor.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Visitor.obj `if test -f 'SynTree/Visitor.cc'; then $(CYGPATH_W) 'SynTree/Visitor.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Visitor.cc'; fi`
-
-SynTree/driver_cfa_cpp-Mutator.o: SynTree/Mutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Mutator.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo -c -o SynTree/driver_cfa_cpp-Mutator.o `test -f 'SynTree/Mutator.cc' || echo '$(srcdir)/'`SynTree/Mutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Mutator.cc' object='SynTree/driver_cfa_cpp-Mutator.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.o `test -f 'SynTree/Mutator.cc' || echo '$(srcdir)/'`SynTree/Mutator.cc
-
-SynTree/driver_cfa_cpp-Mutator.obj: SynTree/Mutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Mutator.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Mutator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='SynTree/Mutator.cc' object='SynTree/driver_cfa_cpp-Mutator.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Mutator.obj `if test -f 'SynTree/Mutator.cc'; then $(CYGPATH_W) 'SynTree/Mutator.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Mutator.cc'; fi`
 
 SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Parser/ExpressionNode.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:17:07 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Sep 27 22:51:55 2017
-// Update Count     : 781
+// Last Modified On : Sat Mar  3 18:22:33 2018
+// Update Count     : 796
 //
 
@@ -58,4 +58,5 @@
 static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
 static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
+static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
 static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
 
@@ -116,5 +117,5 @@
 
 	unsigned long long int v;							// converted integral value
-	size_t last = str.length() - 1;						// last character of constant
+	size_t last = str.length() - 1;						// last subscript of constant
 	Expression * ret;
 
@@ -129,8 +130,18 @@
 	} // if
 
-	if ( str[0] == '0' ) {								// octal/hex constant ?
+	// Cannot be "0"
+
+	if ( str[0] == '0' ) {								// radix character ?
 		dec = false;
-		if ( last != 0 && checkX( str[1] ) ) {			// hex constant ?
+		if ( checkX( str[1] ) ) {						// hex constant ?
 			sscanf( (char *)str.c_str(), "%llx", &v );
+			//printf( "%llx %llu\n", v, v );
+		} else if ( checkB( str[1] ) ) {				// binary constant ?
+			v = 0;
+			for ( unsigned int i = 2;; i += 1 ) {		// compute value
+				if ( str[i] == '1' ) v |= 1;
+			  if ( i == last ) break;
+				v <<= 1;
+			} // for
 			//printf( "%llx %llu\n", v, v );
 		} else {										// octal constant
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Parser/lex.ll	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Thu Feb 22 18:11:27 2018
- * Update Count     : 637
+ * Last Modified On : Sat Mar  3 18:38:16 2018
+ * Update Count     : 640
  */
 
@@ -77,4 +77,5 @@
 %}
 
+binary [0-1]
 octal [0-7]
 nonzero [1-9]
@@ -103,4 +104,8 @@
 nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
 decimal_constant {nonzero_digits}{integer_suffix_opt}
+
+binary_digits ({binary})|({binary}({binary}|"_")*{binary})
+binary_prefix "0"[bB]"_"?
+binary_constant {binary_prefix}{binary_digits}{integer_suffix_opt}
 
 hex_digits ({hex})|({hex}({hex}|"_")*{hex})
@@ -315,6 +320,7 @@
 
 				/* numeric constants */
+{binary_constant} { NUMERIC_RETURN(INTEGERconstant); }
+{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
 {decimal_constant} { NUMERIC_RETURN(INTEGERconstant); }
-{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
 {hex_constant}	{ NUMERIC_RETURN(INTEGERconstant); }
 {floating_decimal}	{ NUMERIC_RETURN(FLOATING_DECIMALconstant); } // must appear before floating_constant
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/ResolvExpr/Resolver.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -788,4 +788,5 @@
 		stmtExpr->accept( resolver );
 		stmtExpr->computeResult();
+		// xxx - aggregate the environments from all statements? Possibly in AlternativeFinder instead?
 	}
 
@@ -793,22 +794,22 @@
 		visit_children = false;
 		// xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
-		maybeAccept( ctorInit->get_ctor(), *visitor );
-		maybeAccept( ctorInit->get_dtor(), *visitor );
+		maybeAccept( ctorInit->ctor, *visitor );
+		maybeAccept( ctorInit->dtor, *visitor );
 
 		// found a constructor - can get rid of C-style initializer
-		delete ctorInit->get_init();
-		ctorInit->set_init( NULL );
+		delete ctorInit->init;
+		ctorInit->init = nullptr;
 
 		// intrinsic single parameter constructors and destructors do nothing. Since this was
 		// implicitly generated, there's no way for it to have side effects, so get rid of it
 		// to clean up generated code.
-		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
-			delete ctorInit->get_ctor();
-			ctorInit->set_ctor( NULL );
-		}
-
-		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
-			delete ctorInit->get_dtor();
-			ctorInit->set_dtor( NULL );
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
+			delete ctorInit->ctor;
+			ctorInit->ctor = nullptr;
+		}
+
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
+			delete ctorInit->dtor;
+			ctorInit->dtor = nullptr;
 		}
 
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -118,4 +118,18 @@
 			env.push_back( newClass );
 		} // for
+	}
+
+	void TypeEnvironment::add( const TypeSubstitution & sub ) {
+		EqvClass newClass;
+		for ( auto p : sub ) {
+			newClass.vars.insert( p.first );
+			newClass.type = p.second->clone();
+			newClass.allowWidening = false;
+			// Minimal assumptions. Not technically correct, but might be good enough, and
+			// is the best we can do at the moment since information is lost in the
+			// transition to TypeSubstitution
+			newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false };
+			add( newClass );
+		}
 	}
 
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/ResolvExpr/TypeEnvironment.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -76,4 +76,5 @@
 		void add( const EqvClass &eqvClass );
 		void add( const Type::ForallList &tyDecls );
+		void add( const TypeSubstitution & sub );
 		template< typename SynTreeClass > int apply( SynTreeClass *&type ) const;
 		template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const;
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ 	(revision )
@@ -1,127 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Mutator.cc --
-//
-// Author           : Richard C. Bilson
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 15:39:37 2017
-// Update Count     : 27
-//
-
-#include <cassert>             // for assert
-#include <list>                // for list
-
-#include "Attribute.h"         // for Attribute
-#include "Declaration.h"       // for ObjectDecl, Declaration, DeclarationWi...
-#include "Expression.h"        // for Expression, ConstantExpr, ConditionalExpr
-#include "Initializer.h"       // for ConstructorInit, Initializer, Designation
-#include "Mutator.h"
-#include "Statement.h"         // for Statement, CatchStmt, AsmStmt, ForStmt
-#include "Type.h"              // for Type, Type::ForallList, AttrType, Arra...
-#include "TypeSubstitution.h"  // for TypeSubstitution
-
-class Constant;
-class Subrange;
-
-Mutator::Mutator() {}
-
-Mutator::~Mutator() {}
-
-Type * Mutator::mutate( TupleType *tupleType ) {
-	mutateAll( tupleType->get_forall(), *this );
-	mutateAll( tupleType->get_types(), *this );
-	mutateAll( tupleType->get_members(), *this );
-	return tupleType;
-}
-
-Type * Mutator::mutate( TypeofType *typeofType ) {
-	assert( typeofType->get_expr() );
-	typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) );
-	return typeofType;
-}
-
-Type * Mutator::mutate( AttrType *attrType ) {
-	if ( attrType->get_isType() ) {
-		assert( attrType->get_type() );
-		attrType->set_type( attrType->get_type()->acceptMutator( *this ) );
-	} else {
-		assert( attrType->get_expr() );
-		attrType->set_expr( attrType->get_expr()->acceptMutator( *this ) );
-	}
-	return attrType;
-}
-
-Type * Mutator::mutate( VarArgsType *varArgsType ) {
-	mutateAll( varArgsType->get_forall(), *this );
-	return varArgsType;
-}
-
-Type * Mutator::mutate( ZeroType *zeroType ) {
-	mutateAll( zeroType->get_forall(), *this );
-	return zeroType;
-}
-
-Type * Mutator::mutate( OneType *oneType ) {
-	mutateAll( oneType->get_forall(), *this );
-	return oneType;
-}
-
-
-Designation * Mutator::mutate( Designation * designation ) {
-	mutateAll( designation->get_designators(), *this );
-	return designation;
-}
-
-Initializer * Mutator::mutate( SingleInit *singleInit ) {
-	singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
-	return singleInit;
-}
-
-Initializer * Mutator::mutate( ListInit *listInit ) {
-	mutateAll( listInit->get_designations(), *this );
-	mutateAll( listInit->get_initializers(), *this );
-	return listInit;
-}
-
-Initializer * Mutator::mutate( ConstructorInit *ctorInit ) {
-	ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
-	ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) );
-	ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
-	return ctorInit;
-}
-
-
-Subrange * Mutator::mutate( Subrange *subrange ) {
-	return subrange;
-}
-
-
-Constant * Mutator::mutate( Constant *constant ) {
-	return constant;
-}
-
-Attribute * Mutator::mutate( Attribute * attribute ) {
-	mutateAll( attribute->parameters, *this );
-	return attribute;
-}
-
-TypeSubstitution * Mutator::mutate( TypeSubstitution * sub ) {
-	for ( auto & p : sub->typeEnv ) {
-		p.second = maybeMutate( p.second, *this );
-	}
-	for ( auto & p : sub->varEnv ) {
-		p.second = maybeMutate( p.second, *this );
-	}
-	return sub;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/Mutator.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -22,6 +22,6 @@
 class Mutator {
   protected:
-	Mutator();
-	virtual ~Mutator();
+	Mutator() = default;
+	virtual ~Mutator() = default;
   public:
 	virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) = 0;
Index: src/SynTree/TypeSubstitution.cc
===================================================================
--- src/SynTree/TypeSubstitution.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/TypeSubstitution.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -104,4 +104,28 @@
 bool TypeSubstitution::empty() const {
 	return typeEnv.empty() && varEnv.empty();
+}
+
+namespace {
+	struct EnvTrimmer {
+		TypeSubstitution * env, * newEnv;
+		EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
+		void previsit( TypeDecl * tyDecl ) {
+			// transfer known bindings for seen type variables
+			if ( Type * t = env->lookup( tyDecl->name ) ) {
+				newEnv->add( tyDecl->name, t );
+			}
+		}
+	};
+} // namespace
+
+/// reduce environment to just the parts that are referenced in a given expression
+TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {
+	if ( env ) {
+		TypeSubstitution * newEnv = new TypeSubstitution();
+		PassVisitor<EnvTrimmer> trimmer( env, newEnv );
+		expr->accept( trimmer );
+		return newEnv;
+	}
+	return nullptr;
 }
 
Index: src/SynTree/TypeSubstitution.h
===================================================================
--- src/SynTree/TypeSubstitution.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/TypeSubstitution.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -55,4 +55,7 @@
 	void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
 
+	/// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
+	static TypeSubstitution * newFromExpr( Expression * expr, TypeSubstitution * env );
+
 	void normalize();
 
@@ -79,4 +82,11 @@
 	TypeEnvType typeEnv;
 	VarEnvType varEnv;
+
+  public:
+	// has to come after declaration of typeEnv
+	auto begin()       -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
+	auto   end()       -> decltype( typeEnv.  end() ) { return typeEnv.  end(); }
+	auto begin() const -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
+	auto   end() const -> decltype( typeEnv.  end() ) { return typeEnv.  end(); }
 };
 
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ 	(revision )
@@ -1,100 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// Visitor.cc --
-//
-// Author           : Richard C. Bilson
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 15:39:38 2017
-// Update Count     : 29
-//
-
-#include <cassert>        // for assert
-#include <list>           // for list
-
-#include "Attribute.h"    // for Attribute
-#include "Constant.h"     // for Constant
-#include "Declaration.h"  // for DeclarationWithType, ObjectDecl, Declaration
-#include "Expression.h"   // for Expression, ConstantExpr, ImplicitCopyCtorExpr
-#include "Initializer.h"  // for Initializer, Designation, ConstructorInit
-#include "Statement.h"    // for Statement, CatchStmt, AsmStmt, CompoundStmt
-#include "Type.h"         // for Type, Type::ForallList, AttrType, FunctionType
-#include "Visitor.h"
-
-class Subrange;
-
-Visitor::Visitor() {}
-
-Visitor::~Visitor() {}
-
-void Visitor::visit( TupleType *tupleType ) {
-	acceptAll( tupleType->get_forall(), *this );
-	acceptAll( tupleType->get_types(), *this );
-	acceptAll( tupleType->get_members(), *this );
-}
-
-void Visitor::visit( TypeofType *typeofType ) {
-	assert( typeofType->get_expr() );
-	typeofType->get_expr()->accept( *this );
-}
-
-void Visitor::visit( AttrType *attrType ) {
-	if ( attrType->get_isType() ) {
-		assert( attrType->get_type() );
-		attrType->get_type()->accept( *this );
-	} else {
-		assert( attrType->get_expr() );
-		attrType->get_expr()->accept( *this );
-	} // if
-}
-
-void Visitor::visit( VarArgsType *varArgsType ) {
-	acceptAll( varArgsType->get_forall(), *this );
-}
-
-void Visitor::visit( ZeroType *zeroType ) {
-	acceptAll( zeroType->get_forall(), *this );
-}
-
-void Visitor::visit( OneType *oneType ) {
-	acceptAll( oneType->get_forall(), *this );
-}
-
-void Visitor::visit( Designation * designation ) {
-	acceptAll( designation->get_designators(), *this );
-}
-
-void Visitor::visit( SingleInit *singleInit ) {
-	singleInit->get_value()->accept( *this );
-}
-
-void Visitor::visit( ListInit *listInit ) {
-	acceptAll( listInit->get_designations(), *this );
-	acceptAll( listInit->get_initializers(), *this );
-}
-
-void Visitor::visit( ConstructorInit *ctorInit ) {
-	maybeAccept( ctorInit->get_ctor(), *this );
-	maybeAccept( ctorInit->get_dtor(), *this );
-	maybeAccept( ctorInit->get_init(), *this );
-}
-
-
-void Visitor::visit( Subrange * ) {}
-
-
-void Visitor::visit( Constant * ) {}
-
-void Visitor::visit( Attribute * attribute ) {
-	acceptAll( attribute->parameters, *this );
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/Visitor.h	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -21,6 +21,6 @@
 class Visitor {
   protected:
-	Visitor();
-	virtual ~Visitor();
+	Visitor() = default;
+	virtual ~Visitor() = default;
   public:
 	// visit: Default implementation of all functions visits the children
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/SynTree/module.mk	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -46,6 +46,4 @@
        SynTree/TypeDecl.cc \
        SynTree/Initializer.cc \
-       SynTree/Visitor.cc \
-       SynTree/Mutator.cc \
        SynTree/TypeSubstitution.cc \
        SynTree/Attribute.cc \
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/Tuples/TupleAssignment.cc	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -281,12 +281,17 @@
 	}
 
-	// removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator.
+	// removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator, and adds the bindings to the compositeEnv
 	// xxx - maybe this should happen in alternative finder for every StmtExpr?
-	// xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv
 	struct EnvRemover {
 		void previsit( ExprStmt * stmt ) {
-			delete stmt->expr->env;
-			stmt->expr->env = nullptr;
-		}
+			assert( compositeEnv );
+			if ( stmt->expr->env ) {
+				compositeEnv->add( *stmt->expr->env );
+				delete stmt->expr->env;
+				stmt->expr->env = nullptr;
+			}
+		}
+
+		ResolvExpr::TypeEnvironment * compositeEnv = nullptr;
 	};
 
@@ -300,4 +305,5 @@
 			ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
 			PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
+			rm.pass.compositeEnv = &compositeEnv;
 			ctorInit->accept( rm );
 		}
Index: src/libcfa/limits
===================================================================
--- src/libcfa/limits	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/libcfa/limits	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 18:06:52 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul  7 09:33:57 2017
-// Update Count     : 7
+// Last Modified On : Thu Mar  1 16:20:54 2018
+// Update Count     : 13
 //
 
@@ -18,9 +18,17 @@
 // Integral Constants
 
+extern const signed char MIN;
+extern const unsigned char MIN;
 extern const short int MIN;
+extern const unsigned short int MIN;
 extern const int MIN;
+extern const unsigned int MIN;
 extern const long int MIN;
+extern const unsigned long int MIN;
 extern const long long int MIN;
+extern const unsigned long long int MIN;
 
+extern const signed char MAX;
+extern const unsigned char MAX;
 extern const short int MAX;
 extern const unsigned short int MAX;
@@ -33,4 +41,18 @@
 
 // Floating-Point Constants
+
+extern const float MIN;
+extern const double MIN;
+extern const long double MIN;
+extern const float _Complex MIN;
+extern const double _Complex MIN;
+extern const long double _Complex MIN;
+
+extern const float MAX;
+extern const double MAX;
+extern const long double MAX;
+extern const float _Complex MAX;
+extern const double _Complex MAX;
+extern const long double _Complex MAX;
 
 extern const float PI;									// pi
@@ -55,17 +77,24 @@
 extern const long double _2_SQRT_PI;					// 2 / sqrt(pi)
 
-extern const _Complex PI;								// pi
-extern const _Complex PI_2;								// pi / 2
-extern const _Complex PI_4;								// pi / 4
-extern const _Complex _1_PI;							// 1 / pi
-extern const _Complex _2_PI;							// 2 / pi
-extern const _Complex _2_SQRT_PI;						// 2 / sqrt(pi)
+extern const float _Complex PI;							// pi
+extern const float _Complex PI_2;						// pi / 2
+extern const float _Complex PI_4;						// pi / 4
+extern const float _Complex _1_PI;						// 1 / pi
+extern const float _Complex _2_PI;						// 2 / pi
+extern const float _Complex _2_SQRT_PI;					// 2 / sqrt(pi)
 
-extern const long _Complex PI;							// pi
-extern const long _Complex PI_2;						// pi / 2
-extern const long _Complex PI_4;						// pi / 4
-extern const long _Complex _1_PI;						// 1 / pi
-extern const long _Complex _2_PI;						// 2 / pi
-extern const long _Complex _2_SQRT_PI;					// 2 / sqrt(pi)
+extern const double _Complex PI;						// pi
+extern const double _Complex PI_2;						// pi / 2
+extern const double _Complex PI_4;						// pi / 4
+extern const double _Complex _1_PI;						// 1 / pi
+extern const double _Complex _2_PI;						// 2 / pi
+extern const double _Complex _2_SQRT_PI;				// 2 / sqrt(pi)
+
+extern const long double _Complex PI;					// pi
+extern const long double _Complex PI_2;					// pi / 2
+extern const long double _Complex PI_4;					// pi / 4
+extern const long double _Complex _1_PI;				// 1 / pi
+extern const long double _Complex _2_PI;				// 2 / pi
+extern const long double _Complex _2_SQRT_PI;			// 2 / sqrt(pi)
 
 extern const float E;									// e
@@ -93,19 +122,27 @@
 extern const long double _1_SQRT_2;						// 1/sqrt(2)
 
-extern const _Complex E;								// e
-extern const _Complex LOG2_E;							// log_2(e)
-extern const _Complex LOG10_E;							// log_10(e)
-extern const _Complex LN_2;								// log_e(2)
-extern const _Complex LN_10;							// log_e(10)
-extern const _Complex SQRT_2;							// sqrt(2)
-extern const _Complex _1_SQRT_2;						// 1 / sqrt(2)
+extern const float _Complex E;							// e
+extern const float _Complex LOG2_E;						// log_2(e)
+extern const float _Complex LOG10_E;					// log_10(e)
+extern const float _Complex LN_2;						// log_e(2)
+extern const float _Complex LN_10;						// log_e(10)
+extern const float _Complex SQRT_2;						// sqrt(2)
+extern const float _Complex _1_SQRT_2;					// 1 / sqrt(2)
 
-extern const long _Complex E;							// e
-extern const long _Complex LOG2_E;						// log_2(e)
-extern const long _Complex LOG10_E;						// log_10(e)
-extern const long _Complex LN_2;						// log_e(2)
-extern const long _Complex LN_10;						// log_e(10)
-extern const long _Complex SQRT_2;						// sqrt(2)
-extern const long _Complex _1_SQRT_2;					// 1 / sqrt(2)
+extern const double _Complex E;							// e
+extern const double _Complex LOG2_E;					// log_2(e)
+extern const double _Complex LOG10_E;					// log_10(e)
+extern const double _Complex LN_2;						// log_e(2)
+extern const double _Complex LN_10;						// log_e(10)
+extern const double _Complex SQRT_2;					// sqrt(2)
+extern const double _Complex _1_SQRT_2;					// 1 / sqrt(2)
+
+extern const long double _Complex E;					// e
+extern const long double _Complex LOG2_E;				// log_2(e)
+extern const long double _Complex LOG10_E;				// log_10(e)
+extern const long double _Complex LN_2;					// log_e(2)
+extern const long double _Complex LN_10;				// log_e(10)
+extern const long double _Complex SQRT_2;				// sqrt(2)
+extern const long double _Complex _1_SQRT_2;			// 1 / sqrt(2)
 
 // Local Variables: //
Index: src/libcfa/limits.c
===================================================================
--- src/libcfa/limits.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/libcfa/limits.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,110 +10,144 @@
 // Created On       : Wed Apr  6 18:06:52 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Sep 12 10:34:48 2016
-// Update Count     : 17
+// Last Modified On : Thu Mar  1 16:22:51 2018
+// Update Count     : 74
 // 
 
+#include <limits.h>
+#include <float.h>
+#define __USE_GNU										// get M_* constants
+#include <math.h>
+#include <complex.h>
 #include "limits"
 
 // Integral Constants
 
-const short int MIN = -32768;
-const int MIN = -2147483648;
-#if __WORDSIZE == 64
-const long int MIN = -9223372036854775807L - 1L;
-#else
-const long int MIN = (int)MIN;
-#endif // M64
-const long long int MIN = -9223372036854775807LL - 1LL;
+const signed char MIN = SCHAR_MIN;
+const unsigned char MIN = 0;
+const short int MIN = SHRT_MIN;
+const unsigned short int MIN = 0;
+const int MIN = INT_MIN;
+const unsigned int MIN = 0;
+const long int MIN = LONG_MIN;
+const unsigned long int MIN = 0;
+const long long int MIN = LLONG_MIN;
+const unsigned long long int MIN = 0;
 
-const short int MAX = 32767;
-const unsigned short int MAX = 65535;
-const int MAX = 2147483647;
-const unsigned int MAX = 4294967295_U;
-#if __WORDSIZE == 64
-const long int MAX = 9223372036854775807_L;
-#else
-const long int MAX = (int)MAX;
-#endif // M64
-const unsigned long int MAX = 4294967295_U;
-const long long int MAX = 9223372036854775807_LL;
-const unsigned long long int MAX = 18446744073709551615_ULL;
+const signed char MAX = SCHAR_MAX;
+const unsigned char MAX = UCHAR_MAX;
+const short int MAX = SHRT_MAX;
+const unsigned short int MAX = USHRT_MAX;
+const int MAX = INT_MAX;
+const unsigned int MAX = UINT_MAX;
+const long int MAX = LONG_MAX;
+const unsigned long int MAX = ULONG_MAX;
+const long long int MAX = LLONG_MAX;
+const unsigned long long int MAX = ULLONG_MAX;
 
 // Floating-Point Constants
 
-const float PI = 3.141592_F;							// pi
-const float PI_2 = 1.570796_F;							// pi / 2
-const float PI_4 = 0.7853981_F;							// pi / 4
-const float _1_PI = 0.3183098_F;						// 1 / pi
-const float _2_PI = 0.6366197_F;						// 2 / pi
-const float _2_SQRT_PI = 1.128379_F;					// 2 / sqrt(pi)
+const float MIN = FLT_MIN;
+const double MIN = DBL_MIN;
+const long double MIN = LDBL_MIN;
+const float _Complex MIN = __FLT_MIN__ + __FLT_MIN__ * I;
+const double _Complex MIN = DBL_MIN +  DBL_MIN * I;
+const long double _Complex MIN = LDBL_MIN + LDBL_MIN * I;
 
-const double PI = 3.14159265358979323846_D;				// pi
-const double PI_2 = 1.57079632679489661923_D;			// pi / 2
-const double PI_4 = 0.78539816339744830962_D;			// pi / 4
-const double _1_PI = 0.31830988618379067154_D;			// 1 / pi
-const double _2_PI = 0.63661977236758134308_D;			// 2 / pi
-const double _2_SQRT_PI = 1.12837916709551257390_D;		// 2 / sqrt(pi)
+const float MAX = FLT_MAX;
+const double MAX = DBL_MAX;
+const long double MAX = LDBL_MAX;
+const float _Complex MAX = FLT_MAX + FLT_MAX * I;
+const double _Complex MAX = DBL_MAX + DBL_MAX * I;
+const long double _Complex MAX = LDBL_MAX + LDBL_MAX * I;
 
-const long double PI = 3.1415926535897932384626433832795029_DL; // pi
-const long double PI_2 = 1.5707963267948966192313216916397514_DL; // pi / 2
-const long double PI_4 = 0.7853981633974483096156608458198757_DL; // pi / 4
-const long double _1_PI = 0.3183098861837906715377675267450287_DL; // 1 / pi
-const long double _2_PI = 0.6366197723675813430755350534900574_DL; // 2 / pi
-const long double _2_SQRT_PI = 1.1283791670955125738961589031215452_DL; // 2 / sqrt(pi)
+const float PI = (float)M_PI;							// pi
+const float PI_2 = (float)M_PI_2;						// pi / 2
+const float PI_4 = (float)M_PI_4;						// pi / 4
+const float _1_PI = (float)M_1_PI;						// 1 / pi
+const float _2_PI = (float)M_2_PI;						// 2 / pi
+const float _2_SQRT_PI = (float)M_2_SQRTPI;				// 2 / sqrt(pi)
 
-const double _Complex PI = 3.14159265358979323846_D+0.0_iD;	// pi
-const double _Complex PI_2 = 1.57079632679489661923_D+0.0_iD; // pi / 2
-const double _Complex PI_4 = 0.78539816339744830962_D+0.0_iD; // pi / 4
-const double _Complex _1_PI = 0.31830988618379067154_D+0.0_iD; // 1 / pi
-const double _Complex _2_PI = 0.63661977236758134308_D+0.0_iD; // 2 / pi
-const double _Complex _2_SQRT_PI = 1.12837916709551257390_D+0.0_iD; // 2 / sqrt(pi)
+const double PI = M_PI;									// pi
+const double PI_2 = M_PI_2;								// pi / 2
+const double PI_4 = M_PI_4;								// pi / 4
+const double _1_PI = M_1_PI;							// 1 / pi
+const double _2_PI = M_2_PI;							// 2 / pi
+const double _2_SQRT_PI = M_2_SQRTPI;					// 2 / sqrt(pi)
 
-const long double _Complex PI = 3.1415926535897932384626433832795029_L+0.0iL; // pi
-const long double _Complex PI_2 = 1.5707963267948966192313216916397514_L+0.0iL; // pi / 2
-const long double _Complex PI_4 = 0.7853981633974483096156608458198757_L+0.0iL; // pi / 4
-const long double _Complex _1_PI = 0.3183098861837906715377675267450287_L+0.0iL; // 1 / pi
-const long double _Complex _2_PI = 0.6366197723675813430755350534900574_L+0.0iL; // 2 / pi
-const long double _Complex _2_SQRT_PI = 1.1283791670955125738961589031215452_L+0.0iL; // 2 / sqrt(pi)
+const long double PI = M_PIl;							// pi
+const long double PI_2 = M_PI_2l;						// pi / 2
+const long double PI_4 = M_PI_4l;						// pi / 4
+const long double _1_PI = M_1_PIl;						// 1 / pi
+const long double _2_PI = M_2_PIl;						// 2 / pi
+const long double _2_SQRT_PI = M_2_SQRTPIl;				// 2 / sqrt(pi)
 
-const float E = 2.718281;								// e
-const float LOG2_E = 1.442695;							// log_2(e)
-const float LOG10_E = 0.4342944;						// log_10(e)
-const float LN_2 = 0.6931471;							// log_e(2)
-const float LN_10 = 2.302585;							// log_e(10)
-const float SQRT_2 = 1.414213;							// sqrt(2)
-const float _1_SQRT_2 = 0.7071067;						// 1 / sqrt(2)
+const float _Complex PI = (float)M_PI + 0.0_iF;			// pi
+const float _Complex PI_2 = (float)M_PI_2 + 0.0_iF;		// pi / 2
+const float _Complex PI_4 = (float)M_PI_4 + 0.0_iF;		// pi / 4
+const float _Complex _1_PI = (float)M_1_PI + 0.0_iF;	// 1 / pi
+const float _Complex _2_PI = (float)M_2_PI + 0.0_iF;	// 2 / pi
+const float _Complex _2_SQRT_PI = (float)M_2_SQRTPI + 0.0_iF; // 2 / sqrt(pi)
 
-const double E = 2.7182818284590452354_D;				// e
-const double LOG2_E = 1.4426950408889634074_D;			// log_2(e)
-const double LOG10_E = 0.43429448190325182765_D;		// log_10(e)
-const double LN_2 = 0.69314718055994530942_D;			// log_e(2)
-const double LN_10 = 2.30258509299404568402_D;			// log_e(10)
-const double SQRT_2 = 1.41421356237309504880_D;			// sqrt(2)
-const double _1_SQRT_2 = 0.70710678118654752440_D;		// 1 / sqrt(2)
+const double _Complex PI = M_PI + 0.0_iD;				// pi
+const double _Complex PI_2 = M_PI_2 + 0.0_iD;			// pi / 2
+const double _Complex PI_4 = M_PI_4 + 0.0_iD;			// pi / 4
+const double _Complex _1_PI = M_1_PI + 0.0_iD;			// 1 / pi
+const double _Complex _2_PI = M_2_PI + 0.0_iD;			// 2 / pi
+const double _Complex _2_SQRT_PI = M_2_SQRTPI + 0.0_iD;	// 2 / sqrt(pi)
 
-const long double E = 2.7182818284590452353602874713526625_DL; // e
-const long double LOG2_E = 1.4426950408889634073599246810018921_DL; // log_2(e)
-const long double LOG10_E = 0.4342944819032518276511289189166051_DL; // log_10(e)
-const long double LN_2 = 0.6931471805599453094172321214581766_DL; // log_e(2)
-const long double LN_10 = 2.3025850929940456840179914546843642_DL; // log_e(10)
-const long double SQRT_2 = 1.4142135623730950488016887242096981_DL; // sqrt(2)
-const long double _1_SQRT_2 = 0.7071067811865475244008443621048490_DL; // 1/sqrt(2)
+const long double _Complex PI = M_PIl + 0.0_iL;			// pi
+const long double _Complex PI_2 = M_PI_2l + 0.0_iL;		// pi / 2
+const long double _Complex PI_4 = M_PI_4l + 0.0_iL;		// pi / 4
+const long double _Complex _1_PI = M_1_PIl + 0.0_iL;	// 1 / pi
+const long double _Complex _2_PI = M_2_PIl + 0.0_iL;	// 2 / pi
+const long double _Complex _2_SQRT_PI = M_2_SQRTPIl + 0.0_iL; // 2 / sqrt(pi)
 
-const double _Complex E = 2.7182818284590452354_D+0.0_iD; // e
-const double _Complex LOG2_E = 1.4426950408889634074_D+0.0_iD; // log_2(e)
-const double _Complex LOG10_E = 0.43429448190325182765_D+0.0_iD; // log_10(e)
-const double _Complex LN_2 = 0.69314718055994530942_D+0.0_iD; // log_e(2)
-const double _Complex LN_10 = 2.30258509299404568402_D+0.0_iD; // log_e(10)
-const double _Complex SQRT_2 = 1.41421356237309504880_D+0.0_iD; // sqrt(2)
-const double _Complex _1_SQRT_2 = 0.70710678118654752440_D+0.0_iD; // 1 / sqrt(2)
+const float E = (float)M_E;								// e
+const float LOG2_E = (float)M_LOG2E;					// log_2(e)
+const float LOG10_E = (float)M_LOG10E;					// log_10(e)
+const float LN_2 = (float)M_LN2;						// log_e(2)
+const float LN_10 = (float)M_LN10;						// log_e(10)
+const float SQRT_2 = (float)M_SQRT2;					// sqrt(2)
+const float _1_SQRT_2 = (float)M_SQRT1_2;				// 1 / sqrt(2)
 
-const long double _Complex E = 2.7182818284590452353602874713526625_L+0.0_iL; // e
-const long double _Complex LOG2_E = 1.4426950408889634073599246810018921_L+0.0_iL; // log_2(e)
-const long double _Complex LOG10_E = 0.4342944819032518276511289189166051_L+0.0_iL; // log_10(e)
-const long double _Complex LN_2 = 0.6931471805599453094172321214581766_L+0.0_iL; // log_e(2)
-const long double _Complex LN_10 = 2.3025850929940456840179914546843642_L+0.0_iL; // log_e(10)
-const long double _Complex SQRT_2 = 1.4142135623730950488016887242096981_L+0.0_iL; // sqrt(2)
-const long double _Complex _1_SQRT_2 = 0.7071067811865475244008443621048490_L+0.0_iL; // 1 / sqrt(2)
+const double E = M_E;									// e
+const double LOG2_E = M_LOG2E;							// log_2(e)
+const double LOG10_E = M_LOG10E;						// log_10(e)
+const double LN_2 = M_LN2;								// log_e(2)
+const double LN_10 = M_LN10;							// log_e(10)
+const double SQRT_2 = M_SQRT2;							// sqrt(2)
+const double _1_SQRT_2 = M_SQRT1_2;						// 1 / sqrt(2)
+
+const long double E = M_El;								// e
+const long double LOG2_E = M_LOG2El;					// log_2(e)
+const long double LOG10_E = M_LOG10El;					// log_10(e)
+const long double LN_2 = M_LN2l;						// log_e(2)
+const long double LN_10 = M_LN10l;						// log_e(10)
+const long double SQRT_2 = M_SQRT2l;					// sqrt(2)
+const long double _1_SQRT_2 = M_SQRT1_2l;				// 1 / sqrt(2)
+
+const float _Complex E = M_E + 0.0_iF;					// e
+const float _Complex LOG2_E = M_LOG2E + 0.0_iF;			// log_2(e)
+const float _Complex LOG10_E = M_LOG10E + 0.0_iF;		// log_10(e)
+const float _Complex LN_2 = M_LN2 + 0.0_iF;				// log_e(2)
+const float _Complex LN_10 = M_LN10 + 0.0_iF;			// log_e(10)
+const float _Complex SQRT_2 = M_SQRT2 + 0.0_iF;			// sqrt(2)
+const float _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iF;	// 1 / sqrt(2)
+
+const double _Complex E = M_E + 0.0_iD;					// e
+const double _Complex LOG2_E = M_LOG2E + 0.0_iD;		// log_2(e)
+const double _Complex LOG10_E = M_LOG10E + 0.0_iD;		// log_10(e)
+const double _Complex LN_2 = M_LN2 + 0.0_iD;			// log_e(2)
+const double _Complex LN_10 = M_LN10 + 0.0_iD;			// log_e(10)
+const double _Complex SQRT_2 = M_SQRT2 + 0.0_iD;		// sqrt(2)
+const double _Complex _1_SQRT_2 = M_SQRT1_2 + 0.0_iD;	// 1 / sqrt(2)
+
+const long double _Complex E = M_El + 0.0_iL;			// e
+const long double _Complex LOG2_E = M_LOG2El + 0.0_iL;	// log_2(e)
+const long double _Complex LOG10_E = M_LOG10El + 0.0_iL; // log_10(e)
+const long double _Complex LN_2 = M_LN2l + 0.0_iL;		// log_e(2)
+const long double _Complex LN_10 = M_LN10l + 0.0_iL;	// log_e(10)
+const long double _Complex SQRT_2 = M_SQRT2l + 0.0_iL;	// sqrt(2)
+const long double _Complex _1_SQRT_2 = M_SQRT1_2l + 0.0_iL; // 1 / sqrt(2)
 
 // Local Variables: //
Index: src/tests/.expect/KRfunctions.x86.txt
===================================================================
--- src/tests/.expect/KRfunctions.x86.txt	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/.expect/KRfunctions.x86.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -82,7 +82,7 @@
     signed int __a__i_2;
     signed int __b__i_2;
-    signed int *(*_tmp_cp_ret0)(signed int __x__i_1, signed int __y__i_1);
-    ((void)(__x__PFPi_ii__2=(((void)(_tmp_cp_ret0=__f10__FPFPi_ii__iPiPid__1(3, (&__a__i_2), (&__b__i_2), 3.5))) , _tmp_cp_ret0)));
-    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    signed int *(*_tmp_cp_ret2)(signed int __x__i_1, signed int __y__i_1);
+    ((void)(__x__PFPi_ii__2=(((void)(_tmp_cp_ret2=__f10__FPFPi_ii__iPiPid__1(3, (&__a__i_2), (&__b__i_2), 3.5))) , _tmp_cp_ret2)));
+    ((void)(_tmp_cp_ret2) /* ^?{} */);
     const signed int __f1__FCi_iPiPi__2(signed int __a__i_2, signed int *__b__Pi_2, signed int *__c__Pi_2){
         __attribute__ ((unused)) const signed int ___retval_f1__Ci_2;
Index: src/tests/.expect/literals.x64.txt
===================================================================
--- src/tests/.expect/literals.x64.txt	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/.expect/literals.x64.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -522,4 +522,28 @@
 signed int __main__Fi___1(){
     __attribute__ ((unused)) signed int ___retval_main__i_1;
+    ((void)0b01101011);
+    ((void)0b01101011u);
+    ((void)0b01101011l);
+    ((void)0b01101011ll);
+    ((void)0b01101011ul);
+    ((void)0b01101011lu);
+    ((void)0b01101011ull);
+    ((void)0b01101011llu);
+    ((void)(+0b01101011));
+    ((void)(+0b01101011u));
+    ((void)(+0b01101011l));
+    ((void)(+0b01101011ll));
+    ((void)(+0b01101011ul));
+    ((void)(+0b01101011lu));
+    ((void)(+0b01101011ull));
+    ((void)(+0b01101011llu));
+    ((void)(-0b01101011));
+    ((void)(-0b01101011u));
+    ((void)(-0b01101011l));
+    ((void)(-0b01101011ll));
+    ((void)(-0b01101011ul));
+    ((void)(-0b01101011lu));
+    ((void)(-0b01101011ull));
+    ((void)(-0b01101011llu));
     ((void)01234567);
     ((void)01234567u);
@@ -1017,4 +1041,34 @@
     ((void)(-0X0123456789.0123456789P-09F));
     ((void)(-0X0123456789.0123456789P-09L));
+    ((void)((signed char )0b01101011));
+    ((void)((signed short int )0b01101011));
+    ((void)((signed int )0b01101011));
+    ((void)((signed long int )0b01101011));
+    ((void)((__int128 )0b01101011));
+    ((void)((unsigned char )0b01101011u));
+    ((void)((signed short int )0b01101011u));
+    ((void)((unsigned int )0b01101011u));
+    ((void)((signed long int )0b01101011u));
+    ((void)((__int128 )0b01101011u));
+    ((void)(+((signed int )((signed char )0b01101011))));
+    ((void)(+((signed int )((signed short int )0b01101011))));
+    ((void)(+((signed int )0b01101011)));
+    ((void)(+((signed long int )0b01101011)));
+    ((void)(+((float )((__int128 )0b01101011))));
+    ((void)(+((signed int )((unsigned char )0b01101011u))));
+    ((void)(+((signed int )((signed short int )0b01101011u))));
+    ((void)(+((unsigned int )0b01101011u)));
+    ((void)(+((signed long int )0b01101011u)));
+    ((void)(+((float )((__int128 )0b01101011u))));
+    ((void)(-((signed int )((signed char )0b01101011))));
+    ((void)(-((signed int )((signed short int )0b01101011))));
+    ((void)(-((signed int )0b01101011)));
+    ((void)(-((signed long int )0b01101011)));
+    ((void)(-((float )((__int128 )0b01101011))));
+    ((void)(-((signed int )((unsigned char )0b01101011u))));
+    ((void)(-((signed int )((signed short int )0b01101011u))));
+    ((void)(-((unsigned int )0b01101011u)));
+    ((void)(-((signed long int )0b01101011u)));
+    ((void)(-((float )((__int128 )0b01101011u))));
     ((void)((signed char )01234567));
     ((void)((signed short int )01234567));
Index: src/tests/.expect/user_literals.txt
===================================================================
--- src/tests/.expect/user_literals.txt	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/.expect/user_literals.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -1,8 +1,9 @@
 11.0714285714286
-11.07225
+15
 11.0714285714286
+24.8
+11.248
 11.0714285714286
-11.0714285714286
-22.0457142857143
+28.0657142857143
 secs 1
 secs 23
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/Makefile.am	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -123,2 +123,5 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
 
+# Warnings
+warnings/self-assignment: warnings/self-assignment.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/Makefile.in	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -800,4 +800,8 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
 
+# Warnings
+warnings/self-assignment: warnings/self-assignment.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
Index: src/tests/limits.c
===================================================================
--- src/tests/limits.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/limits.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Tue May 10 20:44:20 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 10 20:45:28 2016
-// Update Count     : 1
+// Last Modified On : Thu Mar  1 16:21:55 2018
+// Update Count     : 7
 //
 
@@ -18,9 +18,17 @@
 // Integral Constants
 
+signed char m = MIN;
+unsigned char m = MIN;
 short int m = MIN;
+unsigned short int m = MIN;
 int m = MIN;
+unsigned int m = MIN;
 long int m = MIN;
+unsigned long int m = MIN;
 long long int m = MIN;
+unsigned long long int m = MIN;
 
+signed char M = MAX;
+unsigned char M = MAX;
 short int M = MAX;
 unsigned short int M = MAX;
@@ -33,4 +41,18 @@
 
 // Floating-Point Constants
+
+float m = MIN;
+double m = MIN;
+long double m = MIN;
+float _Complex m = MIN;
+double _Complex m = MIN;
+long double _Complex m = MIN;
+
+float M = MAX;
+double M = MAX;
+long double M = MAX;
+float _Complex M = MAX;
+double _Complex M = MAX;
+long double _Complex M = MAX;
 
 float pi = PI;
@@ -55,17 +77,24 @@
 long double _2_sqrt_pi = _2_SQRT_PI;
 
-_Complex pi = PI;
-_Complex pi_2 = PI_2;
-_Complex pi_4 = PI_4;
-_Complex _1_pi = _1_PI;
-_Complex _2_pi = _2_PI;
-_Complex _2_sqrt_pi = _2_SQRT_PI;
+float _Complex pi = PI;
+float _Complex pi_2 = PI_2;
+float _Complex pi_4 = PI_4;
+float _Complex _1_pi = _1_PI;
+float _Complex _2_pi = _2_PI;
+float _Complex _2_sqrt_pi = _2_SQRT_PI;
 
-long _Complex pi = PI;
-long _Complex pi_2 = PI_2;
-long _Complex pi_4 = PI_4;
-long _Complex _1_pi = _1_PI;
-long _Complex _2_pi = _2_PI;
-long _Complex _2_sqrt_pi = _2_SQRT_PI;
+double _Complex pi = PI;
+double _Complex pi_2 = PI_2;
+double _Complex pi_4 = PI_4;
+double _Complex _1_pi = _1_PI;
+double _Complex _2_pi = _2_PI;
+double _Complex _2_sqrt_pi = _2_SQRT_PI;
+
+long double _Complex pi = PI;
+long double _Complex pi_2 = PI_2;
+long double _Complex pi_4 = PI_4;
+long double _Complex _1_pi = _1_PI;
+long double _Complex _2_pi = _2_PI;
+long double _Complex _2_sqrt_pi = _2_SQRT_PI;
 
 float e = E;
@@ -93,19 +122,27 @@
 long double _1_sqrt_2 = _1_SQRT_2;
 
-_Complex e = E;
-_Complex log2_e = LOG2_E;
-_Complex log10_e = LOG10_E;
-_Complex ln_2 = LN_2;
-_Complex ln_10 = LN_10;
-_Complex sqrt_2 = SQRT_2;
-_Complex _1_sqrt_2 = _1_SQRT_2;
+float _Complex e = E;
+float _Complex log2_e = LOG2_E;
+float _Complex log10_e = LOG10_E;
+float _Complex ln_2 = LN_2;
+float _Complex ln_10 = LN_10;
+float _Complex sqrt_2 = SQRT_2;
+float _Complex _1_sqrt_2 = _1_SQRT_2;
 
-long _Complex e = E;
-long _Complex log2_e = LOG2_E;
-long _Complex log10_e = LOG10_E;
-long _Complex ln_2 = LN_2;
-long _Complex ln_10 = LN_10;
-long _Complex sqrt_2 = SQRT_2;
-long _Complex _1_sqrt_2 = _1_SQRT_2;
+double _Complex e = E;
+double _Complex log2_e = LOG2_E;
+double _Complex log10_e = LOG10_E;
+double _Complex ln_2 = LN_2;
+double _Complex ln_10 = LN_10;
+double _Complex sqrt_2 = SQRT_2;
+double _Complex _1_sqrt_2 = _1_SQRT_2;
+
+long double _Complex e = E;
+long double _Complex log2_e = LOG2_E;
+long double _Complex log10_e = LOG10_E;
+long double _Complex ln_2 = LN_2;
+long double _Complex ln_10 = LN_10;
+long double _Complex sqrt_2 = SQRT_2;
+long double _Complex _1_sqrt_2 = _1_SQRT_2;
 
 int main(int argc, char const *argv[]) {
Index: src/tests/literals.c
===================================================================
--- src/tests/literals.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/literals.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  9 16:34:38 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Sep 25 20:26:00 2017
-// Update Count     : 132
+// Last Modified On : Sun Mar  4 10:41:31 2018
+// Update Count     : 134
 // 
 
@@ -31,4 +31,9 @@
 // integer literals
 
+	// binary
+	 0b01101011;   0b01101011u;   0b01101011l;   0b01101011ll;   0b01101011ul;   0b01101011lu;   0b01101011ull;   0b01101011llu;
+	+0b01101011;  +0b01101011u;  +0b01101011l;  +0b01101011ll;  +0b01101011ul;  +0b01101011lu;  +0b01101011ull;  +0b01101011llu;
+	-0b01101011;  -0b01101011u;  -0b01101011l;  -0b01101011ll;  -0b01101011ul;  -0b01101011lu;  -0b01101011ull;  -0b01101011llu;
+
 	// octal
 	 01234567;   01234567u;   01234567l;   01234567ll;   01234567ul;   01234567lu;   01234567ull;   01234567llu;
@@ -148,4 +153,9 @@
 #ifdef __CFA__
 // fixed-size length
+
+	// binary
+	 0b01101011_l8;   0b01101011_l16;   0b01101011_l32;   0b01101011_l64;   0b01101011_l128;   0b01101011_l8u;   0b01101011_ul16;   0b01101011_l32u;   0b01101011_ul64;   0b01101011_ul128;
+	+0b01101011_l8;  +0b01101011_l16;  +0b01101011_l32;  +0b01101011_l64;  +0b01101011_l128;  +0b01101011_l8u;  +0b01101011_ul16;  +0b01101011_l32u;  +0b01101011_ul64;  +0b01101011_ul128;
+	-0b01101011_l8;  -0b01101011_l16;  -0b01101011_l32;  -0b01101011_l64;  -0b01101011_l128;  -0b01101011_l8u;  -0b01101011_ul16;  -0b01101011_l32u;  -0b01101011_ul64;  -0b01101011_ul128;
 
 	// octal
Index: src/tests/user_literals.c
===================================================================
--- src/tests/user_literals.c	(revision 094476de228cd8cb7d6a34066aacd6b8adb12617)
+++ src/tests/user_literals.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -10,6 +10,6 @@
 // Created On       : Wed Sep  6 21:40:50 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Dec  7 09:12:36 2017
-// Update Count     : 50
+// Last Modified On : Sun Mar  4 11:14:02 2018
+// Update Count     : 52
 // 
 
@@ -31,30 +31,31 @@
 
 
-struct Weight {
-	double stones;
-};
-void ?{}( Weight & w ) { w.stones = 0; }				// operations
+struct Weight { double stones; };
+void ?{}( Weight & w ) { w.stones = 0; }
 void ?{}( Weight & w, double w ) { w.stones = w; }
-Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
+Weight ?+?( Weight l, Weight r ) {
+	return (Weight){ l.stones + r.stones };
+}
 ofstream & ?|?( ofstream & os, Weight w ) { return os | w.stones; }
 
 Weight ?`st( double w ) { return (Weight){ w }; }		// backquote for user literals
 Weight ?`lb( double w ) { return (Weight){ w / 14.0 }; }
-Weight ?`kg( double w ) { return (Weight) { w * 0.1575}; }
-
+Weight ?`kg( double w ) { return (Weight) { w * 0.16 }; }
 
 int main() {
-	Weight w, hw = { 14 };								// 14 stone
-	w = 11`st + 1`lb;
+	Weight w, heavy = { 20 };							// 20 stone
+	w = 155`lb;
+	sout | w | endl;
+	w = 0b_1111`st;
+	sout | w | endl;
+	w = 0_233`lb;										// octal weight (155)
+	sout | w | endl;
+	w = 0x_9b_u`kg;
 	sout | w | endl;
 	w = 70.3`kg;
 	sout | w | endl;
-	w = 155`lb;
+	w = 11`st + 1`lb;
 	sout | w | endl;
-	w = 0x_9b_u`lb;										// hexadecimal unsigned weight (155)
-	sout | w | endl;
-	w = 0_233`lb;										// octal weight (155)
-	sout | w | endl;
-	w = 5`st + 8`kg + 25`lb + hw;
+	w = 5`st + 8`kg + 25`lb + heavy;
 	sout | w | endl;
 
Index: src/tests/warnings/.expect/self-assignment.txt
===================================================================
--- src/tests/warnings/.expect/self-assignment.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
+++ src/tests/warnings/.expect/self-assignment.txt	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -0,0 +1,25 @@
+warnings/self-assignment.c:29:1 warning: self assignment of expression: Cast of:
+  Variable Expression: j: signed int
+... to:
+  reference to signed int
+warnings/self-assignment.c:30:1 warning: self assignment of expression: Cast of:
+  Variable Expression: s: instance of struct S with body 1 
+... to:
+  reference to instance of struct S with body 1 
+warnings/self-assignment.c:31:1 warning: self assignment of expression: Cast of:
+  Member Expression, with field: 
+    i: signed int
+  ... from aggregate: 
+    Variable Expression: s: instance of struct S with body 1 
+... to:
+  reference to signed int
+warnings/self-assignment.c:32:1 warning: self assignment of expression: Cast of:
+  Member Expression, with field: 
+    i: signed int
+  ... from aggregate: 
+    Member Expression, with field: 
+      s: instance of struct S with body 1 
+    ... from aggregate: 
+      Variable Expression: t: instance of struct T with body 1 
+... to:
+  reference to signed int
Index: src/tests/warnings/self-assignment.c
===================================================================
--- src/tests/warnings/self-assignment.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
+++ src/tests/warnings/self-assignment.c	(revision caa649b9dc5ac77e3114ebf86f767d903959d155)
@@ -0,0 +1,38 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// self-assignment.c --
+//
+// Author           : Rob Schluntz
+// Created On       : Thu Mar 1 13:53:57 2018
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Mar 1 13:53:57 2018
+// Update Count     : 2
+//
+
+struct S {
+  int i;
+};
+
+struct T {
+  S s;
+};
+
+int main() {
+  int j = 0;
+  S s = { 0 };
+  T t = { { 0 } };
+
+  j = j;
+  s = s;
+  s.i = s.i;
+  t.s.i = t.s.i;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa dtor-early-exit" //
+// End: //
