Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 8780e30b2d0cf8d3c7765ec0c68824494b453871)
+++ src/GenPoly/Specialize.cc	(revision b3b2077b1feda429f174cfb4f374cb1e00580630)
@@ -147,5 +147,5 @@
 
 	Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
-		assert( actual->has_result() );
+		assertf( actual->has_result(), "attempting to specialize an untyped expression" );
 		if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
 			FunctionType *funType;
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 8780e30b2d0cf8d3c7765ec0c68824494b453871)
+++ src/InitTweak/FixInit.cc	(revision b3b2077b1feda429f174cfb4f374cb1e00580630)
@@ -509,17 +509,15 @@
 					// an AddressExpr.  Effectively, this turns
 					//   lvalue T f();
-					//   &*f()
+					//   &*f();
 					// into
+					//   T * f();
 					//   T * tmp_cp_retN;
-					//   tmp_cp_ret_N = &*(tmp_cp_ret_N = &*f(), tmp_cp_ret);
+					//   &*(tmp_cp_retN = &*f(), tmp_cp_retN);		// the first * and second & are generated here
 					// 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->set_result( resultType );
-					retExpr = deref;
+					retExpr->set_result( new PointerType( Type::Qualifiers(), retExpr->get_result() ) );
+					retExpr = UntypedExpr::createDeref( retExpr );
 				} // if
 				retExpr->set_env( env->clone() );
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 8780e30b2d0cf8d3c7765ec0c68824494b453871)
+++ src/SymTab/Validate.cc	(revision b3b2077b1feda429f174cfb4f374cb1e00580630)
@@ -241,5 +241,5 @@
 		return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
 	}
-
+	// xxx - shouldn't this be declsToAddBefore?
 	template< typename AggDecl >
 	void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 8780e30b2d0cf8d3c7765ec0c68824494b453871)
+++ src/SynTree/Expression.cc	(revision b3b2077b1feda429f174cfb4f374cb1e00580630)
@@ -380,4 +380,29 @@
 }
 
+UntypedExpr * UntypedExpr::createDeref( Expression * expr ) {
+	UntypedExpr * ret = new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ expr } );
+	if ( Type * type = expr->get_result() ) {
+		Type * base = InitTweak::getPointerBase( type );
+		if ( ! base ) {
+			std::cerr << type << std::endl;
+		}
+		assertf( base, "expected pointer type in dereference\n" );
+		ret->set_result( maybeClone( base ) );
+	}
+	return ret;
+}
+
+UntypedExpr * UntypedExpr::createAssign( Expression * arg1, Expression * arg2 ) {
+	assert( arg1 && arg2 );
+	UntypedExpr * ret = new UntypedExpr( new NameExpr( "?=?" ), std::list< Expression * >{ arg1, arg2 } );
+	if ( arg1->get_result() && arg2->get_result() ) {
+		// if both expressions are typed, assumes that this assignment is a C bitwise assignment,
+		// so the result is the type of the RHS
+		ret->set_result( arg2->get_result()->clone() );
+	}
+	return ret;
+}
+
+
 void UntypedExpr::print( std::ostream &os, int indent ) const {
 	os << "Applying untyped: " << std::endl;
@@ -446,9 +471,12 @@
 
 void ConditionalExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Conditional expression on: " << std::endl;
+	os << "Conditional expression on: " << std::endl;
+	os << std::string( indent+2, ' ' );
 	arg1->print( os, indent+2 );
 	os << std::string( indent, ' ' ) << "First alternative:" << std::endl;
+	os << std::string( indent+2, ' ' );
 	arg2->print( os, indent+2 );
 	os << std::string( indent, ' ' ) << "Second alternative:" << std::endl;
+	os << std::string( indent+2, ' ' );
 	arg3->print( os, indent+2 );
 	os << std::endl;
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 8780e30b2d0cf8d3c7765ec0c68824494b453871)
+++ src/SynTree/Expression.h	(revision b3b2077b1feda429f174cfb4f374cb1e00580630)
@@ -111,4 +111,7 @@
 	std::list<Expression*>& get_args() { return args; }
 
+	static UntypedExpr * createDeref( Expression * arg );
+	static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 );
+
 	virtual UntypedExpr *clone() const { return new UntypedExpr( *this ); }
 	virtual void accept( Visitor &v ) { v.visit( this ); }
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 8780e30b2d0cf8d3c7765ec0c68824494b453871)
+++ src/Tuples/TupleAssignment.cc	(revision b3b2077b1feda429f174cfb4f374cb1e00580630)
@@ -9,6 +9,6 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:02:53 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Nov 9 13:48:42 2016
 // Update Count     : 2
 //
@@ -180,4 +180,5 @@
 		// explode the lhs so that each field of the tuple-valued-expr is assigned.
 		explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs) );
+
 		// and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed
 		if ( isCast ) {
@@ -192,8 +193,7 @@
 			}
 		}
-		// }
-	}
-
-	TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter,const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
+	}
+
+	TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) {
 		assert( alts.size() == 1 || alts.size() == 2 );
 		if ( alts.size() == 2 ) {
@@ -210,5 +210,5 @@
 		assert( left );
 		std::list< Expression * > args;
-		args.push_back( new AddressExpr( new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ new VariableExpr( left ) } ) ) );
+		args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) );
 		// args.push_back( new AddressExpr( new VariableExpr( left ) ) );
 		if ( right ) args.push_back( new VariableExpr( right ) );
@@ -238,4 +238,5 @@
 		static UniqueName lhsNamer( "__multassign_L" );
 		static UniqueName rhsNamer( "__multassign_R" );
+
 		// xxx - need more complicated matching?
 		if ( lhs.size() == rhs.size() ) {
