Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision a0fdbd51112d9506c6a29aefc759d19bbb0828fe)
+++ src/GenPoly/Box.cc	(revision fea7ca72a864654b68ee68c30d09b8423c12bc64)
@@ -10,5 +10,5 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Mon Apr 18 13:22:15 2016
+// Last Modified On : Fri Apr 29 12:16:11 2016
 // Update Count     : 295
 //
@@ -911,4 +911,5 @@
 				} else if ( arg->get_results().front()->get_isLvalue() ) {
 					// VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
+					// xxx - need to test that this code is still reachable
 					if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
 						commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
@@ -1346,6 +1347,9 @@
 				} // if
 			} // if
+			// isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
+			// out of the if condition.
+			bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );
 			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
-			if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
+			if ( polytype || needs ) {
 				Expression *ret = addrExpr->get_arg();
 				delete ret->get_results().front();
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision a0fdbd51112d9506c6a29aefc759d19bbb0828fe)
+++ src/GenPoly/Specialize.cc	(revision fea7ca72a864654b68ee68c30d09b8423c12bc64)
@@ -10,5 +10,5 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Jan 20 13:00:00 2016
+// Last Modified On : Thu Apr 28 15:17:45 2016
 // Update Count     : 24
 //
@@ -41,7 +41,7 @@
 		virtual Expression * mutate( AddressExpr *castExpr );
 		virtual Expression * mutate( CastExpr *castExpr );
-		virtual Expression * mutate( LogicalExpr *logicalExpr );
-		virtual Expression * mutate( ConditionalExpr *conditionalExpr );
-		virtual Expression * mutate( CommaExpr *commaExpr );
+		// virtual Expression * mutate( LogicalExpr *logicalExpr );
+		// virtual Expression * mutate( ConditionalExpr *conditionalExpr );
+		// virtual Expression * mutate( CommaExpr *commaExpr );
 
 	  private:
@@ -212,15 +212,19 @@
 	}
 
-	Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
-		return logicalExpr;
-	}
-
-	Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
-		return condExpr;
-	}
-
-	Expression * Specialize::mutate( CommaExpr *commaExpr ) {
-		return commaExpr;
-	}
+	// Removing these for now. Richard put these in for some reason, but it's not clear why.
+	// In particular, copy constructors produce a comma expression, and with this code the parts
+	// of that comma expression are not specialized, which causes problems.
+
+	// Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
+	// 	return logicalExpr;
+	// }
+
+	// Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
+	// 	return condExpr;
+	// }
+
+	// Expression * Specialize::mutate( CommaExpr *commaExpr ) {
+	// 	return commaExpr;
+	// }
 } // namespace GenPoly
 
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision a0fdbd51112d9506c6a29aefc759d19bbb0828fe)
+++ src/InitTweak/FixInit.cc	(revision fea7ca72a864654b68ee68c30d09b8423c12bc64)
@@ -10,5 +10,5 @@
 // Created On       : Wed Jan 13 16:29:30 2016
 // Last Modified By : Rob Schluntz
-// Last Modified On : Thu Apr 28 12:25:14 2016
+// Last Modified On : Fri Apr 29 12:25:40 2016
 // Update Count     : 30
 //
@@ -231,5 +231,7 @@
 		callExpr->set_env( impCpCtorExpr->get_env()->clone() );
 		for ( Type * result : appExpr->get_results() ) {
-			ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result->clone(), 0 );
+			result = result->clone();
+			impCpCtorExpr->get_env()->apply( result );
+			ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );
 			ret->get_type()->set_isConst( false );
 			impCpCtorExpr->get_returnDecls().push_back( ret );
@@ -285,6 +287,29 @@
 			// add that onto the assignment expression so that later steps have the necessary information
 			assign->add_result( returnDecl->get_type()->clone() );
-			// return new CommaExpr( assign, new VariableExpr( returnDecl ) );
-			return assign;
+
+			Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
+			if ( callExpr->get_results().front()->get_isLvalue() ) {
+				// lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any
+				// lvalue returning non-intrinsic function. Add an AddressExpr to the call to negate
+				// the derefence and change the type of the return temporary from T to T* to properly
+				// capture the return value. Then dereference the result of the comma expression, since
+				// the lvalue returning call was originally wrapped with an AddressExpr.
+				// Effectively, this turns
+				//   lvalue T f();
+				//   &*f()
+				// into
+				//   T * tmp_cp_retN;
+				//   tmp_cp_ret_N = &*(tmp_cp_ret_N = &*f(), tmp_cp_ret);
+				// which work out in terms of types, but is pretty messy. It would be nice to find a better way.
+				assign->get_args().back() = new AddressExpr( assign->get_args().back() );
+
+				Type * resultType = returnDecl->get_type()->clone();
+				returnDecl->set_type( new PointerType( Type::Qualifiers(), returnDecl->get_type() ) );
+				UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
+				deref->get_args().push_back( retExpr );
+				deref->add_result( resultType );
+				retExpr = deref;
+			}
+			return retExpr;
 		} else {
 			return callExpr;
Index: src/main.cc
===================================================================
--- src/main.cc	(revision a0fdbd51112d9506c6a29aefc759d19bbb0828fe)
+++ src/main.cc	(revision fea7ca72a864654b68ee68c30d09b8423c12bc64)
@@ -10,5 +10,5 @@
 // Created On       : Fri May 15 23:12:02 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Thu Apr 28 12:24:46 2016
+// Last Modified On : Fri Apr 29 12:02:21 2016
 // Update Count     : 200
 //
@@ -61,4 +61,5 @@
 	astp = false,
 	bresolvep = false,
+	bboxp = false,
 	ctorinitp = false,
 	exprp = false,
@@ -76,8 +77,9 @@
 	codegenp = false;
 
-enum { Ast, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
+enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
 
 static struct option long_opts[] = {
 	{ "ast", no_argument, 0, Ast },
+	{ "before-box", no_argument, 0, Bbox },
 	{ "before-resolver", no_argument, 0, Bresolver },
 	{ "ctorinitfix", no_argument, 0, CtorInitFix },
@@ -105,5 +107,5 @@
 
 	int c;
-	while ( (c = getopt_long( argc, argv, "abcefFglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
+	while ( (c = getopt_long( argc, argv, "abBcefFglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
 		switch ( c ) {
 		  case Ast:
@@ -115,6 +117,9 @@
 			bresolvep = true;
 			break;
-			case CtorInitFix:
-			case 'c':
+		  case 'B':										// print before resolver steps
+			bboxp = true;
+			break;
+		  case CtorInitFix:
+		  case 'c':
 			ctorinitp = true;
 			break;
@@ -292,4 +297,9 @@
 		OPTPRINT( "convertLvalue" )
 		GenPoly::convertLvalue( translationUnit );
+
+		if ( bboxp ) {
+			dump( translationUnit );
+			return 0;
+		}
 		OPTPRINT( "box" )
 		GenPoly::box( translationUnit );
