Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/InitTweak/FixInit.cc	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
@@ -35,10 +35,10 @@
 #include "GenPoly/DeclMutator.h"
 #include "SynTree/AddStmtVisitor.h"
-#include "CodeGen/GenType.h"  // for warnings
-
-bool ctordtorp = false;
-bool ctorp = false;
-bool cpctorp = false;
-bool dtorp = false;
+#include "CodeGen/GenType.h"  // for warning/error messages
+
+bool ctordtorp = false; // print all debug
+bool ctorp = false; // print ctor debug
+bool cpctorp = false; // print copy ctor debug
+bool dtorp = false; // print dtor debug
 #define PRINT( text ) if ( ctordtorp ) { text }
 #define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text }
@@ -47,7 +47,4 @@
 namespace InitTweak {
 	namespace {
-		const std::list<Label> noLabels;
-		const std::list<Expression*> noDesignators;
-
 		class InsertImplicitCalls : public GenPoly::PolyMutator {
 		public:
@@ -957,4 +954,5 @@
 		Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
 			static UniqueName tempNamer( "_tmp_ctor_expr" );
+			// xxx - is the size check necessary?
 			assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
 			ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/InitTweak/GenInit.cc	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
@@ -265,4 +265,36 @@
 	}
 
+	ConstructorInit * genCtorInit( ObjectDecl * objDecl ) {
+		// call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
+		// for each constructable object
+		std::list< Statement * > ctor;
+		std::list< Statement * > dtor;
+
+		InitExpander srcParam( objDecl->get_init() );
+		InitExpander nullParam( (Initializer *)NULL );
+		SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
+		SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
+
+		// Currently genImplicitCall produces a single Statement - a CompoundStmt
+		// which  wraps everything that needs to happen. As such, it's technically
+		// possible to use a Statement ** in the above calls, but this is inherently
+		// unsafe, so instead we take the slightly less efficient route, but will be
+		// immediately informed if somehow the above assumption is broken. In this case,
+		// we could always wrap the list of statements at this point with a CompoundStmt,
+		// but it seems reasonable at the moment for this to be done by genImplicitCall
+		// itself. It is possible that genImplicitCall produces no statements (e.g. if
+		// an array type does not have a dimension). In this case, it's fine to ignore
+		// the object for the purposes of construction.
+		assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
+		if ( ctor.size() == 1 ) {
+			// need to remember init expression, in case no ctors exist
+			// if ctor does exist, want to use ctor expression instead of init
+			// push this decision to the resolver
+			assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
+			return new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() );
+		}
+		return nullptr;
+	}
+
 	DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
 		handleDWT( objDecl );
@@ -275,32 +307,5 @@
 			if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl );
 
-			// call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
-			// for each constructable object
-			std::list< Statement * > ctor;
-			std::list< Statement * > dtor;
-
-			InitExpander srcParam( objDecl->get_init() );
-			InitExpander nullParam( (Initializer *)NULL );
-			SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
-			SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
-
-			// Currently genImplicitCall produces a single Statement - a CompoundStmt
-			// which  wraps everything that needs to happen. As such, it's technically
-			// possible to use a Statement ** in the above calls, but this is inherently
-			// unsafe, so instead we take the slightly less efficient route, but will be
-			// immediately informed if somehow the above assumption is broken. In this case,
-			// we could always wrap the list of statements at this point with a CompoundStmt,
-			// but it seems reasonable at the moment for this to be done by genImplicitCall
-			// itself. It is possible that genImplicitCall produces no statements (e.g. if
-			// an array type does not have a dimension). In this case, it's fine to ignore
-			// the object for the purposes of construction.
-			assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
-			if ( ctor.size() == 1 ) {
-				// need to remember init expression, in case no ctors exist
-				// if ctor does exist, want to use ctor expression instead of init
-				// push this decision to the resolver
-				assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
-				objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
-			}
+			objDecl->set_init( genCtorInit( objDecl ) );
 		}
 		return Parent::mutate( objDecl );
Index: src/InitTweak/GenInit.h
===================================================================
--- src/InitTweak/GenInit.h	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/InitTweak/GenInit.h	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// RemoveInit.h --
+// GenInit.h --
 //
 // Author           : Rodolfo G. Esteves
@@ -27,4 +27,7 @@
 	/// Adds return value temporaries and wraps Initializers in ConstructorInit nodes
 	void genInit( std::list< Declaration * > & translationUnit );
+
+	/// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
+	ConstructorInit * genCtorInit( ObjectDecl * objDecl );
 } // namespace
 
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/SynTree/Initializer.h	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
@@ -23,4 +23,6 @@
 
 #include <cassert>
+
+const std::list<Expression*> noDesignators;
 
 // Initializer: base class for object initializers (provide default values)
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/Tuples/TupleExpansion.cc	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
@@ -28,4 +28,5 @@
 #include "Common/ScopedMap.h"
 #include "ResolvExpr/typeops.h"
+#include "InitTweak/GenInit.h"
 
 namespace Tuples {
@@ -133,5 +134,7 @@
 			return tupleExpr;
 		} else {
-			return memberExpr;
+			// there may be a tuple expr buried in the aggregate
+			// xxx - this is a memory leak
+			return new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) );
 		}
 	}
@@ -142,8 +145,27 @@
 		if ( ! decls.count( unqExpr->get_id() ) ) {
 			// xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location.
-			// xxx - is it possible to make the decl's type const?
-			ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) );
-			decls[unqExpr->get_id()] = decl;
-			addDeclaration( decl );
+
+			// xxx - this doesn't work, because it would need to be placed after fixInit, but fixInit doesn't know (and shouldn't have to know) about the existance of UniqueExprs - i.e. it will visit them twice
+			// need to construct/destruct unique exprs in general - maybe it's not worth it and fixInit should handle UniqueExpr explicitly?
+			// currently, tmp is being destructed before unqExpr is used, which suggests there should be a separate lifetime for unqExpr from the tmp_ret
+
+			// if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( unqExpr->get_expr() ) ) {
+			// 	if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( commaExpr->get_arg2() ) ) {
+			// 		// steal existing decl from expr
+			// 		if ( ObjectDecl * decl = dynamic_cast< ObjectDecl * >( varExpr->get_var() ) ) {
+			// 			decls[unqExpr->get_id()] = decl;
+			// 			return unqExpr->get_expr()->clone();
+			// 		}
+			// 	}
+			// }
+
+			// xxx - attach a resolved ConstructorInit node?
+			// xxx - is it possible to make the objDecl's type const?
+			ObjectDecl * objDecl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), nullptr );
+			// must be done on two lines because genCtorInit accesses objDecl's fields
+			objDecl->set_init( InitTweak::genCtorInit( objDecl ) );
+
+			decls[unqExpr->get_id()] = objDecl;
+			addDeclaration( objDecl );
 		}
 		return new VariableExpr( decls[unqExpr->get_id()] );
Index: src/main.cc
===================================================================
--- src/main.cc	(revision bf32bb8a6509388bf221983b0b4c4c8620ff76b9)
+++ src/main.cc	(revision f0121d7b1fdcae6c3362d9920d387c2a83a180d7)
@@ -251,5 +251,5 @@
 		} // if
 
-		OPTPRINT( "expandUniqueExpr" ); // xxx - is this the right place for this?
+		OPTPRINT( "expandUniqueExpr" ); // xxx - is this the right place for this? want to expand ASAP so that subsequent passes don't need to worry about double-visiting a unique expr
 		Tuples::expandUniqueExpr( translationUnit );
 
