Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision d1969a607787c81d78565de2d2aaa145be1680e2)
+++ src/InitTweak/FixInit.cc	(revision d88f256ade0eaa8dd3de01f0df046f5252ccb73e)
@@ -33,4 +33,5 @@
 #include "SymTab/Autogen.h"
 #include "GenPoly/PolyMutator.h"
+#include "GenPoly/DeclMutator.h"
 #include "SynTree/AddStmtVisitor.h"
 #include "CodeGen/GenType.h"  // for warnings
@@ -216,4 +217,12 @@
 			SymTab::Indexer & indexer;
 		};
+
+		class FixCtorExprs : public GenPoly::DeclMutator {
+		  public:
+			/// expands ConstructorExpr nodes into comma expressions, using a temporary for the first argument
+			static void fix( std::list< Declaration * > & translationUnit );
+
+			virtual Expression * mutate( ConstructorExpr * ctorExpr );
+		};
 	} // namespace
 
@@ -221,4 +230,5 @@
 		// fixes ConstructorInit for global variables. should happen before fixInitializers.
 		InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
+
 
 		InsertImplicitCalls::insert( translationUnit );
@@ -231,4 +241,12 @@
 
 		GenStructMemberCalls::generate( translationUnit );
+		// xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
+		// hack in the way untyped assignments are generated, where the first argument cannot have
+		// its address taken because of the way codegeneration handles UntypedExpr vs. ApplicationExpr.
+		// Thus such assignment exprs must never pushed through expression resolution (and thus should
+		// not go through the FixCopyCtors pass), otherwise they will fail -- guaranteed.
+		// Also needs to happen after GenStructMemberCalls, since otherwise member constructors exprs
+		// don't look right, and a member can be constructed more than once.
+		FixCtorExprs::fix( translationUnit );
 	}
 
@@ -283,4 +301,9 @@
 				throw warner.errors;
 			}
+		}
+
+		void FixCtorExprs::fix( std::list< Declaration * > & translationUnit ) {
+			FixCtorExprs fixer;
+			fixer.mutateDeclarationList( translationUnit );
 		}
 
@@ -480,6 +503,5 @@
 					retExpr = deref;
 				} // if
-				// xxx - might need to set env on retExpr...
-				// retExpr->set_env( env->clone() );
+				retExpr->set_env( env->clone() );
 				return retExpr;
 			} else {
@@ -914,4 +936,28 @@
 			return safe_dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untypedExpr, indexer ) );
 		}
+
+		Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
+			static UniqueName tempNamer( "_tmp_ctor_expr" );
+			assert( ctorExpr->get_results().size() == 1 );
+			ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_results().front()->clone(), nullptr );
+			addDeclaration( tmp );
+
+			ApplicationExpr * callExpr = safe_dynamic_cast< ApplicationExpr * > ( ctorExpr->get_callExpr() );
+			TypeSubstitution * env = ctorExpr->get_env();
+			ctorExpr->set_callExpr( nullptr );
+			ctorExpr->set_env( nullptr );
+
+			Expression *& firstArg = callExpr->get_args().front();
+			UntypedExpr * assign = new UntypedExpr( new NameExpr( "?=?" ) );
+			assign->get_args().push_back( new VariableExpr( tmp ) );
+			assign->get_args().push_back( firstArg );
+			cloneAll( ctorExpr->get_results(), assign->get_results() );
+			firstArg = assign;
+
+			CommaExpr * commaExpr = new CommaExpr( callExpr, new VariableExpr( tmp ) );
+			commaExpr->set_env( env );
+			delete ctorExpr;
+			return commaExpr;
+		}
 	} // namespace
 } // namespace InitTweak
