Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 93401f82a63159fae2fe2dfe080b1b6408bd5c26)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 5a806be44b4fa01503e31893d182ea2d9eb394c7)
@@ -204,8 +204,9 @@
 	} // namespace
 
-	void referenceToRvalueConversion( Expression *& expr ) {
+	void referenceToRvalueConversion( Expression *& expr, Cost & cost ) {
 		if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
 			// cast away reference from expr
 			expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
+			cost.incReference();
 		}
 	}
@@ -435,5 +436,5 @@
 					PRINT( std::cerr << "end of formals with varargs function: inc unsafe: " << convCost << std::endl; ; )
 					// convert reference-typed expressions to value-typed expressions
-					referenceToRvalueConversion( *actualExpr );
+					referenceToRvalueConversion( *actualExpr, convCost );
 					continue;
 				} else {
@@ -565,5 +566,6 @@
 				// DOESN'T WORK: grandchild nodes conflict with their cousins
 				//if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
-				Expression *varExpr = data.combine();
+
+				Expression *varExpr = data.combine( newerAlt.cost );
 				delete varExpr->get_result();
 				varExpr->set_result( adjType->clone() );
@@ -1121,5 +1123,5 @@
 					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
 						Alternative newFunc( *func );
-						referenceToRvalueConversion( newFunc.expr );
+						referenceToRvalueConversion( newFunc.expr, newFunc.cost );
 						makeFunctionAlternatives( newFunc, function, argExpansions,
 							std::back_inserter( candidates ) );
@@ -1130,5 +1132,5 @@
 						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
 							Alternative newFunc( *func );
-							referenceToRvalueConversion( newFunc.expr );
+							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
 							makeFunctionAlternatives( newFunc, function, argExpansions,
 								std::back_inserter( candidates ) );
@@ -1160,5 +1162,5 @@
 								dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
 							Alternative newFunc( *funcOp );
-							referenceToRvalueConversion( newFunc.expr );
+							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
 							makeFunctionAlternatives( newFunc, function, argExpansions,
 								std::back_inserter( candidates ) );
@@ -1344,17 +1346,16 @@
 		for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
 			// it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
-			std::unique_ptr<Expression> aggrExpr( agg->expr->clone() );
-			Type * aggrType = aggrExpr->get_result();
-			if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
-				aggrType = aggrType->stripReferences();
-				aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
-			}
+			Cost cost = agg->cost;
+			Expression * aggrExpr = agg->expr->clone();
+			referenceToRvalueConversion( aggrExpr, cost );
+			std::unique_ptr<Expression> guard( aggrExpr );
+
 			// find member of the given type
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( structInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
+				addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( unionInst, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
+				addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
 			} else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
-				addTupleMembers( tupleType, aggrExpr.get(), agg->cost, agg->env, memberExpr->get_member() );
+				addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
 			} // if
 		} // for
@@ -1370,7 +1371,7 @@
 		PRINT( std::cerr << "nameExpr is " << nameExpr->name << std::endl; )
 		for ( auto & data : declList ) {
-			Expression * newExpr = data.combine();
-			// xxx - add in extra cost for with-statement exprs?
-			alternatives.push_back( Alternative( newExpr, env, Cost::zero ) );
+			Cost cost = Cost::zero;
+			Expression * newExpr = data.combine( cost );
+			alternatives.push_back( Alternative( newExpr, env, Cost::zero ) ); // xxx
 			PRINT(
 				std::cerr << "decl is ";
@@ -1412,5 +1413,5 @@
 			// return the lowest cost alternative for the argument
 			Alternative &choice = winners.front();
-			referenceToRvalueConversion( choice.expr );
+			referenceToRvalueConversion( choice.expr, choice.cost );
 			alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
 		} // if
@@ -1433,5 +1434,5 @@
 			// return the lowest cost alternative for the argument
 			Alternative &choice = winners.front();
-			referenceToRvalueConversion( choice.expr );
+			referenceToRvalueConversion( choice.expr, choice.cost );
 			alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
 		} // if
@@ -1485,5 +1486,7 @@
 			AltList & alternatives = finder.get_alternatives();
 			if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
-				alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) );
+				Cost cost = Cost::zero;
+				Expression * newExpr = data.combine( cost );
+				alternatives.push_back( Alternative( new AttrExpr( newExpr, argType->clone() ), env, cost ) );
 				for ( DeclarationWithType * retVal : function->returnVals ) {
 					alternatives.back().expr->result = retVal->get_type()->clone();
@@ -1522,5 +1525,7 @@
 		} else {
 			for ( auto & data : attrList ) {
-				alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) );
+				Cost cost = Cost::zero;
+				Expression * newExpr = data.combine( cost );
+				alternatives.push_back( Alternative( newExpr, env, cost ) );
 				renameTypes( alternatives.back().expr );
 			} // for
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 93401f82a63159fae2fe2dfe080b1b6408bd5c26)
+++ src/ResolvExpr/Resolver.cc	(revision 5a806be44b4fa01503e31893d182ea2d9eb394c7)
@@ -526,5 +526,5 @@
 					Alternative newFunc( func );
 					// Strip reference from function
-					referenceToRvalueConversion( newFunc.expr );
+					referenceToRvalueConversion( newFunc.expr, newFunc.cost );
 
 					// For all the set of arguments we have try to match it with the parameter of the current function alternative
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision 93401f82a63159fae2fe2dfe080b1b6408bd5c26)
+++ src/ResolvExpr/typeops.h	(revision 5a806be44b4fa01503e31893d182ea2d9eb394c7)
@@ -106,5 +106,5 @@
 
 	// in AlternativeFinder.cc
-	void referenceToRvalueConversion( Expression *& expr );
+	void referenceToRvalueConversion( Expression *& expr, Cost & cost );
 
 	// flatten tuple type into list of types
