Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/Lvalue.cc	(revision 74b007ba1f2facc85656ade19a8bab1d56bb0a82)
@@ -30,5 +30,7 @@
 
 #include "ResolvExpr/Resolver.h"
+#include "ResolvExpr/TypeEnvironment.h"
 #include "ResolvExpr/typeops.h"
+#include "ResolvExpr/Unify.h"
 
 #include "Common/UniqueName.h"
@@ -64,6 +66,4 @@
 
 		struct ReferenceConversions final {
-			void premutate( AddressExpr * addrExpr );
-
 			Expression * postmutate( CastExpr * castExpr );
 			Expression * postmutate( AddressExpr * addrExpr );
@@ -89,4 +89,8 @@
 		struct GeneralizedLvalue final : public WithVisitorRef<GeneralizedLvalue> {
 			Expression * postmutate( AddressExpr * addressExpr );
+			Expression * postmutate( MemberExpr * memExpr );
+
+			template<typename Func>
+			Expression * applyTransformation( Expression * expr, Expression * arg, Func mkExpr );
 		};
 
@@ -133,4 +137,9 @@
 		// from this point forward, no other pass should create reference types.
 		referencesEliminated = true;
+	}
+
+	Expression * generalizedLvalue( Expression * expr ) {
+		PassVisitor<GeneralizedLvalue> genLval;
+		return expr->acceptMutator( genLval );
 	}
 
@@ -359,24 +368,42 @@
 		}
 
-		Expression * GeneralizedLvalue::postmutate( AddressExpr * addrExpr ) {
-			if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( addrExpr->get_arg() ) ) {
+		template<typename Func>
+		Expression * GeneralizedLvalue::applyTransformation( Expression * expr, Expression * arg, Func mkExpr ) {
+			if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( arg ) ) {
 				Expression * arg1 = commaExpr->get_arg1()->clone();
 				Expression * arg2 = commaExpr->get_arg2()->clone();
-				Expression * ret = new CommaExpr( arg1, (new AddressExpr( arg2 ))->acceptMutator( *visitor ) );
-				ret->set_env( addrExpr->get_env() );
-				addrExpr->set_env( nullptr );
-				delete addrExpr;
-				return ret;
-			} else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( addrExpr->get_arg() ) ) {
+				Expression * ret = new CommaExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ) );
+				ret->set_env( expr->get_env() );
+				expr->set_env( nullptr );
+				delete expr;
+				return ret;
+			} else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( arg ) ) {
 				Expression * arg1 = condExpr->get_arg1()->clone();
 				Expression * arg2 = condExpr->get_arg2()->clone();
 				Expression * arg3 = condExpr->get_arg3()->clone();
-				Expression * ret = new ConditionalExpr( arg1, (new AddressExpr( arg2 ))->acceptMutator( *visitor ), (new AddressExpr( arg3 ))->acceptMutator( *visitor ) );
-				ret->set_env( addrExpr->get_env() );
-				addrExpr->set_env( nullptr );
-				delete addrExpr;
-				return ret;
-			}
-			return addrExpr;
+				ConditionalExpr * ret = new ConditionalExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ), mkExpr( arg3 )->acceptMutator( *visitor ) );
+				ret->set_env( expr->get_env() );
+				expr->set_env( nullptr );
+				delete expr;
+
+				// conditional expr type may not be either of the argument types, need to unify
+				using namespace ResolvExpr;
+				Type* commonType = nullptr;
+				TypeEnvironment newEnv;
+				AssertionSet needAssertions, haveAssertions;
+				OpenVarSet openVars;
+				unify( ret->get_arg2()->get_result(), ret->get_arg3()->get_result(), newEnv, needAssertions, haveAssertions, openVars, SymTab::Indexer(), commonType );
+				ret->set_result( commonType ? commonType : ret->get_arg2()->get_result()->clone() );
+				return ret;
+			}
+			return expr;
+		}
+
+		Expression * GeneralizedLvalue::postmutate( MemberExpr * memExpr ) {
+			return applyTransformation( memExpr, memExpr->get_aggregate(), [=]( Expression * aggr ) { return new MemberExpr( memExpr->get_member(), aggr ); } );
+		}
+
+		Expression * GeneralizedLvalue::postmutate( AddressExpr * addrExpr ) {
+			return applyTransformation( addrExpr, addrExpr->get_arg(), []( Expression * arg ) { return new AddressExpr( arg ); } );
 		}
 
