Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:52:08 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jul 25 22:37:46 2019
-// Update Count     : 37
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:35:00 2019
+// Update Count     : 38
 //
 
@@ -377,5 +377,6 @@
 	}
 
-	Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
+	Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
 		PRINT(
 			std::cerr << std::endl << "converting ";
@@ -387,5 +388,5 @@
 			std::cerr << std::endl;
 		)
-		Cost convCost = conversionCost( actualType, formalType, indexer, env );
+		Cost convCost = conversionCost( actualType, formalType, actualIsLvalue, indexer, env );
 		PRINT(
 			std::cerr << std::endl << "cost is " << convCost << std::endl;
@@ -402,5 +403,6 @@
 
 	Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
-		Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
+		Cost convCost = computeConversionCost(
+			actualExpr->result, formalType, actualExpr->get_lvalue(), indexer, env );
 
 		// if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
@@ -1213,6 +1215,6 @@
 			unify( castExpr->result, alt.expr->result, alt.env, needAssertions,
 				haveAssertions, openVars, indexer );
-			Cost thisCost = castCost( alt.expr->result, castExpr->result, indexer,
-				alt.env );
+			Cost thisCost = castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(),
+				indexer, alt.env );
 			PRINT(
 				std::cerr << "working on cast with result: " << castExpr->result << std::endl;
@@ -1641,5 +1643,6 @@
 				// xxx - do some inspecting on this line... why isn't result bound to initAlt.type?
 
-				Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv );
+				Cost thisCost = castCost( alt.expr->result, toType, alt.expr->get_lvalue(),
+					indexer, newEnv );
 				if ( thisCost != Cost::infinity ) {
 					// count one safe conversion for each value that is thrown away
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/ResolvExpr/CastCost.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 06:57:43 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb  2 15:34:36 2016
-// Update Count     : 7
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:12:00 2019
+// Update Count     : 8
 //
 
@@ -37,5 +37,6 @@
 	struct CastCost_old : public ConversionCost {
 	  public:
-		CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
+		CastCost_old( const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
 
 		using ConversionCost::previsit;
@@ -45,9 +46,10 @@
 	};
 
-	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
-					return castCost( src, eqvClass->type, indexer, env );
+					return castCost( src, eqvClass->type, srcIsLvalue, indexer, env );
 				} else {
 					return Cost::infinity;
@@ -57,5 +59,5 @@
 				const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
 				if ( type->base ) {
-					return castCost( src, type->base, indexer, env ) + Cost::safe;
+					return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe;
 				} // if
 			} // if
@@ -78,11 +80,11 @@
 		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
+			return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
 				return ptrsCastable( t1, t2, env, indexer );
 			});
 		} else {
 			PassVisitor<CastCost_old> converter(
-				dest, indexer, env,
-				(Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
+				dest, srcIsLvalue, indexer, env,
+				(Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & ))
 					castCost );
 			src->accept( converter );
@@ -96,6 +98,7 @@
 	}
 
-	CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
-		: ConversionCost( dest, indexer, env, costFunc ) {
+	CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+		: ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) {
 	}
 
@@ -106,5 +109,5 @@
 			cost = Cost::unsafe;
 		} else {
-			cost = conversionCost( basicType, dest, indexer, env );
+			cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env );
 		} // if
 	}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/ResolvExpr/ConversionCost.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 07:06:19 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Jun 24 13:33:00 2019
-// Update Count     : 26
+// Last Modified On : Mon Aug 12 10:21:00 2019
+// Update Count     : 27
 //
 
@@ -46,10 +46,11 @@
 #endif
 
-	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
+	Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
 		if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
 			if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
 				if ( eqvClass->type ) {
-					return conversionCost( src, eqvClass->type, indexer, env );
+					return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
 				} else {
 					return Cost::infinity;
@@ -61,5 +62,6 @@
 				assert( type );
 				if ( type->base ) {
-					return conversionCost( src, type->base, indexer, env ) + Cost::safe;
+					return conversionCost( src, type->base, srcIsLvalue, indexer, env )
+						+ Cost::safe;
 				} // if
 			} // if
@@ -81,11 +83,11 @@
 		} else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
 			PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
-			return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
+			return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
 				return ptrsAssignable( t1, t2, env );
 			});
 		} else {
 			PassVisitor<ConversionCost> converter(
-				dest, indexer, env,
-				(Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
+				dest, srcIsLvalue, indexer, env,
+				(Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
 					conversionCost );
 			src->accept( converter );
@@ -98,14 +100,19 @@
 	}
 
-	static Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
+			int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
 		if ( diff > 0 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
+			Cost cost = convertToReferenceCost(
+				strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
+				diff-1, indexer, env, func );
 			cost.incReference();
 			return cost;
 		} else if ( diff < -1 ) {
 			// TODO: document this
-			Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
+			Cost cost = convertToReferenceCost(
+				src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
+				diff+1, indexer, env, func );
 			cost.incReference();
 			return cost;
@@ -138,6 +145,6 @@
 				PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
 				PassVisitor<ConversionCost> converter(
-					dest, indexer, env,
-					(Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
+					dest, srcIsLvalue, indexer, env,
+					(Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
 						conversionCost );
 				src->accept( converter );
@@ -150,5 +157,6 @@
 			if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
 				PRINT( std::cerr << "converting compatible base type" << std::endl; )
-				if ( src->get_lvalue() ) {
+				assert( src->get_lvalue() == srcIsLvalue );
+				if ( srcIsLvalue ) {
 					PRINT(
 						std::cerr << "lvalue to reference conversion" << std::endl;
@@ -178,13 +186,14 @@
 	}
 
-	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
+			const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
 		int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
-		Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
+		Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
 		PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
 		return cost;
 	}
 
-	ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
-		: dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
+	ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
+		: dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
 	}
 
@@ -371,5 +380,5 @@
 		// recursively compute conversion cost from T1 to T2.
 		// cv can be safely dropped because of 'implicit dereference' behavior.
-		cost = costFunc( refType->base, dest, indexer, env );
+		cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
 		if ( refType->base->tq == dest->tq ) {
 			cost.incReference();  // prefer exact qualifiers
@@ -403,5 +412,5 @@
 		static Type::Qualifiers q;
 		static BasicType integer( q, BasicType::SignedInt );
-		cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
+		cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
 		if ( cost < Cost::unsafe ) {
 			cost.incSafe();
@@ -413,5 +422,5 @@
 	void ConversionCost::postvisit( const TypeInstType * inst ) {
 		if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
-			cost = costFunc( eqvClass->type, dest, indexer, env );
+			cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env );
 		} else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
 			if ( inst->name == destAsInst->name ) {
@@ -423,5 +432,5 @@
 			assert( type );
 			if ( type->base ) {
-				cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
+				cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
 			} // if
 		} // if
@@ -434,5 +443,5 @@
 			std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
 			while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
-				Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env );
+				Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
 				if ( newCost == Cost::infinity ) {
 					return;
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/ResolvExpr/ConversionCost.h	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 09:37:28 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Mon Jun 24 10:00:00 2019
-// Update Count     : 5
+// Last Modified On : Thu Aug  8 16:13:00 2019
+// Update Count     : 6
 //
 
@@ -33,8 +33,11 @@
 	class TypeEnvironment;
 
-	typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
+	typedef std::function<Cost(const Type *, const Type *, bool,
+		const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
+
 	struct ConversionCost : public WithShortCircuiting {
 	  public:
-		ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
+		ConversionCost( const Type * dest, bool srcIsLvalue,
+			const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
 
 		Cost get_cost() const { return cost; }
@@ -59,4 +62,5 @@
 	  protected:
 		const Type * dest;
+		bool srcIsLvalue;
 		const SymTab::Indexer &indexer;
 		Cost cost;
@@ -66,5 +70,6 @@
 
 	typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
-	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
+	Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
 
 // Some function pointer types, differ in return type.
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Aaron B. Moss
 // Created On       : Fri Oct 05 13:46:00 2018
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 10 16:10:37 2019
-// Update Count     : 2
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:47:00 2019
+// Update Count     : 3
 //
 
@@ -156,6 +156,7 @@
 			for ( const auto& assn : x.assns ) {
 				// compute conversion cost from satisfying decl to assertion
+				assert( !assn.match.adjType->get_lvalue() );
 				k += computeConversionCost(
-					assn.match.adjType, assn.decl->get_type(), indexer, x.env );
+					assn.match.adjType, assn.decl->get_type(), false, indexer, x.env );
 
 				// mark vars+specialization cost on function-type assertions
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/ResolvExpr/typeops.h	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 07:28:22 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Feb  8 09:30:34 2019
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Thu Aug  8 16:36:00 2019
+// Update Count     : 5
 //
 
@@ -80,5 +80,6 @@
 
 	// in CastCost.cc
-	Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 	Cost castCost(
 		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
@@ -86,5 +87,6 @@
 
 	// in ConversionCost.cc
-	Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+	Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 	Cost conversionCost(
 		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
@@ -92,5 +94,5 @@
 
 	// in AlternativeFinder.cc
-	Cost computeConversionCost( Type * actualType, Type * formalType,
+	Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
 		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 
Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/SynTree/ApplicationExpr.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Tue Apr 26 12:41:06 2016
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Aug 12 14:28:00 2019
+// Update Count     : 5
 //
 
@@ -76,4 +76,8 @@
 }
 
+bool ApplicationExpr::get_lvalue() const {
+	return result->get_lvalue();
+}
+
 void ApplicationExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Application of" << std::endl << indent+1;
Index: src/SynTree/CommaExpr.cc
===================================================================
--- src/SynTree/CommaExpr.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/SynTree/CommaExpr.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Mon May 02 15:19:44 2016
-// Update Count     : 1
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Arg 12 16:11:00 2016
+// Update Count     : 2
 //
 
@@ -39,4 +39,9 @@
 }
 
+bool CommaExpr::get_lvalue() const {
+	// xxx - as above, shouldn't be an lvalue but that information is used anyways.
+	return result->get_lvalue();
+}
+
 void CommaExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Comma Expression:" << std::endl;
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/SynTree/Expression.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  7 17:03:00 2019
-// Update Count     : 62
+// Last Modified On : Tue Aug 13 11:31:00 2019
+// Update Count     : 63
 //
 
@@ -64,5 +64,6 @@
 
 bool Expression::get_lvalue() const {
-	return result->get_lvalue();
+	assert( !result->get_lvalue() );
+	return false;
 }
 
@@ -138,4 +139,8 @@
 }
 
+bool VariableExpr::get_lvalue() const {
+	return result->get_lvalue();
+}
+
 VariableExpr * VariableExpr::functionPointer( FunctionDecl * func ) {
 	VariableExpr * funcExpr = new VariableExpr( func );
@@ -269,4 +274,8 @@
 CastExpr::~CastExpr() {
 	delete arg;
+}
+
+bool CastExpr::get_lvalue() const {
+	return result->get_lvalue();
 }
 
@@ -380,4 +389,9 @@
 	// don't delete the member declaration, since it points somewhere else in the tree
 	delete aggregate;
+}
+
+bool MemberExpr::get_lvalue() const {
+	assert( result->get_lvalue() );
+	return true;
 }
 
@@ -432,4 +446,7 @@
 }
 
+bool UntypedExpr::get_lvalue() const {
+	return result->get_lvalue();
+}
 
 void UntypedExpr::print( std::ostream & os, Indenter indent ) const {
@@ -490,4 +507,8 @@
 	delete arg2;
 	delete arg3;
+}
+
+bool ConditionalExpr::get_lvalue() const {
+	return result->get_lvalue();
 }
 
@@ -548,4 +569,8 @@
 }
 
+bool ConstructorExpr::get_lvalue() const {
+	return result->get_lvalue();
+}
+
 void ConstructorExpr::print( std::ostream & os, Indenter indent ) const {
 	os <<  "Constructor Expression: " << std::endl << indent+1;
@@ -565,4 +590,9 @@
 CompoundLiteralExpr::~CompoundLiteralExpr() {
 	delete initializer;
+}
+
+bool CompoundLiteralExpr::get_lvalue() const {
+	assert( result->get_lvalue() );
+	return true;
 }
 
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/SynTree/Expression.h	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Wed Aug  7 16:56:00 2019
-// Update Count     : 51
+// Last Modified On : Tue Aug 13 11:30:00 2019
+// Update Count     : 52
 //
 
@@ -71,5 +71,5 @@
 	const Type * get_result() const { return result; }
 	void set_result( Type * newValue ) { result = newValue; }
-	bool get_lvalue() const;
+	virtual bool get_lvalue() const;
 
 	TypeSubstitution * get_env() const { return env; }
@@ -99,4 +99,6 @@
 	virtual ~ApplicationExpr();
 
+	bool get_lvalue() const final;
+
 	Expression * get_function() const { return function; }
 	void set_function( Expression * newValue ) { function = newValue; }
@@ -121,4 +123,6 @@
 	UntypedExpr( const UntypedExpr & other );
 	virtual ~UntypedExpr();
+
+	bool get_lvalue() const final;
 
 	Expression * get_function() const { return function; }
@@ -209,4 +213,6 @@
 	virtual ~CastExpr();
 
+	bool get_lvalue() const final;
+
 	Expression * get_arg() const { return arg; }
 	void set_arg( Expression * newValue ) { arg = newValue; }
@@ -292,4 +298,6 @@
 	virtual ~MemberExpr();
 
+	bool get_lvalue() const final;
+
 	DeclarationWithType * get_member() const { return member; }
 	void set_member( DeclarationWithType * newValue ) { member = newValue; }
@@ -314,4 +322,6 @@
 	VariableExpr( const VariableExpr & other );
 	virtual ~VariableExpr();
+
+	bool get_lvalue() const final;
 
 	DeclarationWithType * get_var() const { return var; }
@@ -501,4 +511,6 @@
 	virtual ~ConditionalExpr();
 
+	bool get_lvalue() const final;
+
 	Expression * get_arg1() const { return arg1; }
 	void set_arg1( Expression * newValue ) { arg1 = newValue; }
@@ -525,4 +537,6 @@
 	virtual ~CommaExpr();
 
+	bool get_lvalue() const final;
+
 	Expression * get_arg1() const { return arg1; }
 	void set_arg1( Expression * newValue ) { arg1 = newValue; }
@@ -611,4 +625,6 @@
 	~ConstructorExpr();
 
+	bool get_lvalue() const final;
+
 	Expression * get_callExpr() const { return callExpr; }
 	void set_callExpr( Expression * newValue ) { callExpr = newValue; }
@@ -629,4 +645,6 @@
 	CompoundLiteralExpr( const CompoundLiteralExpr & other );
 	virtual ~CompoundLiteralExpr();
+
+	bool get_lvalue() const final;
 
 	Initializer * get_initializer() const { return initializer; }
@@ -705,4 +723,6 @@
 	TupleIndexExpr( const TupleIndexExpr & other );
 	virtual ~TupleIndexExpr();
+
+	bool get_lvalue() const final;
 
 	Expression * get_tuple() const { return tuple; }
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision dee1f892debc88dfe69449a54ea03dbb87f3f3d0)
+++ src/SynTree/TupleExpr.cc	(revision 1118b8b06b0fb36e1220cb75d6cf3f6db12cc746)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Mar 17 09:42:29 2017
-// Update Count     : 3
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Aug 12 14:22:00 2019
+// Update Count     : 4
 //
 
@@ -78,4 +78,9 @@
 }
 
+bool TupleIndexExpr::get_lvalue() const {
+	assert( result->get_lvalue() );
+	return true;
+}
+
 void TupleIndexExpr::print( std::ostream &os, Indenter indent ) const {
 	os << "Tuple Index Expression, with tuple:" << std::endl;
