Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision ffad73aefa957693bcf94ebf6ac5c171bb476ce3)
+++ src/GenPoly/Box.cc	(revision 35304009ddd2f96bf13633c8c18b3e3d28cbb924)
@@ -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 : Thu Nov 26 17:01:55 2015
-// Update Count     : 191
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 15 15:30:31 2015
+// Update Count     : 215
 //
 
@@ -62,7 +62,7 @@
 			virtual Expression *mutate( CommaExpr *commaExpr );
 			virtual Expression *mutate( ConditionalExpr *condExpr );
-			virtual Statement *mutate(ReturnStmt *catchStmt);
+			virtual Statement * mutate( ReturnStmt *returnStmt );
 			virtual Type *mutate( PointerType *pointerType );
-			virtual Type *mutate( FunctionType *pointerType );
+			virtual Type * mutate( FunctionType *functionType );
   
 			virtual void doBeginScope();
@@ -192,6 +192,10 @@
 							if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
 								if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
-									name = typeInst->get_name();
-									return true;
+									if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
+										if ( typeInst->get_name() == typeInst2->get_name() ) {
+											name = typeInst->get_name();
+											return true;
+										} // if
+									} // if
 								} // if
 							} // if
@@ -277,5 +281,4 @@
 
 		TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
-///     std::cerr << "add " << typeDecl->get_name() << "\n";
 			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
 			return Mutator::mutate( typeDecl );
@@ -327,23 +330,30 @@
 
 		Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
-			if ( useRetval ) {
-				assert( retval );
-				arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
-				arg++;
-			} else {
-				ObjectDecl *newObj = makeTemporary( retType->clone() );
-				Expression *paramExpr = new VariableExpr( newObj );
-				if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
-					paramExpr = new AddressExpr( paramExpr );
-				} // if
-				arg = appExpr->get_args().insert( arg, paramExpr );
-				arg++;
-///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
-				CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
-				commaExpr->set_env( appExpr->get_env() );
-				appExpr->set_env( 0 );
-				return commaExpr;
-			} // if
-			return appExpr;
+			// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
+			// if ( useRetval ) {
+			// 	assert( retval );
+			// 	arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
+			// 	arg++;
+			// } else {
+
+			// Create temporary to hold return value of polymorphic function and produce that temporary as a result
+			// using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
+			// return values.
+			ObjectDecl *newObj = makeTemporary( retType->clone() );
+			Expression *paramExpr = new VariableExpr( newObj );
+			// If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
+			// temporary is already boxed and can be used directly.
+			if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
+				paramExpr = new AddressExpr( paramExpr );
+			} // if
+			arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
+			arg++;
+			// Build a comma expression to call the function and emulate a normal return.
+			CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
+			commaExpr->set_env( appExpr->get_env() );
+			appExpr->set_env( 0 );
+			return commaExpr;
+			// } // if
+			// return appExpr;
 		}
 
@@ -411,11 +421,5 @@
 
 		void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
-///   std::cout << "function is ";
-///   function->print( std::cout );
 			for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
-///     std::cout << "parameter is ";
-///     (*param)->print( std::fcout );
-///     std::cout << std::endl << "argument is ";
-///     (*arg)->print( std::cout );
 				assert( arg != appExpr->get_args().end() );
 				addCast( *arg, (*param)->get_type(), exprTyVars );
@@ -807,6 +811,24 @@
 		Expression *Pass1::mutate( AddressExpr *addrExpr ) {
 			assert( ! addrExpr->get_arg()->get_results().empty() );
+
+			bool needs = false;
+			if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
+				if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
+					if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
+						if ( name->get_name() == "*?" ) {
+							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
+								assert( ! appExpr->get_function()->get_results().empty() );
+								PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
+								assert( pointer );
+								FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
+								assert( function );
+								needs = needsAdapter( function, scopeTyVars );
+							} // if
+						} // if
+					} // if
+				} // if
+			} // if
 			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
-			if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) {
+			if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
 				Expression *ret = addrExpr->get_arg();
 				delete ret->get_results().front();
@@ -820,39 +842,39 @@
 		}
 
-		Statement * Pass1::mutate(ReturnStmt *retStmt) {
-			// a cast expr on a polymorphic return value is either redundant or invalid
-			while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
-				retStmt->set_expr( castExpr->get_arg() );
-				retStmt->get_expr()->set_env( castExpr->get_env() );
-				castExpr->set_env( 0 );
-				castExpr->set_arg( 0 );
-				delete castExpr;
-			}
-			if ( retval && retStmt->get_expr() ) {
-				assert( ! retStmt->get_expr()->get_results().empty() );
-				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
-///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
-					TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
-					assert( typeInst );
-					std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
-					if ( assignIter == assignOps.end() ) {
-						throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
-					} // if
-					ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
-					Expression *retParm = new NameExpr( retval->get_name() );
-					retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
-					assignExpr->get_args().push_back( retParm );
-					assignExpr->get_args().push_back( retStmt->get_expr() );
-					stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
-				} else {
-					useRetval = true;
-					stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
-					useRetval = false;
+		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
+			if ( retval && returnStmt->get_expr() ) {
+				assert( ! returnStmt->get_expr()->get_results().empty() );
+				// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
+				// if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+				// a cast expr on a polymorphic return value is either redundant or invalid
+				while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
+					returnStmt->set_expr( castExpr->get_arg() );
+					returnStmt->get_expr()->set_env( castExpr->get_env() );
+					castExpr->set_env( 0 );
+					castExpr->set_arg( 0 );
+					delete castExpr;
+				} //while
+				TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
+				assert( typeInst );
+				std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
+				if ( assignIter == assignOps.end() ) {
+					throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
 				} // if
-				retStmt->set_expr( 0 );
+				ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
+				Expression *retParm = new NameExpr( retval->get_name() );
+				retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
+				assignExpr->get_args().push_back( retParm );
+				assignExpr->get_args().push_back( returnStmt->get_expr() );
+				stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
+				// } else {
+				// 	useRetval = true;
+				// 	stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
+				// 	useRetval = false;
+				// } // if
+				returnStmt->set_expr( 0 );
 			} else {
-				retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
-			} // if
-			return retStmt;
+				returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
+			} // if
+			return returnStmt;
 		}
 
@@ -905,5 +927,5 @@
 				}
 			}
-///  deleteAll( functions );
+//  deleteAll( functions );
 		}
 
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision ffad73aefa957693bcf94ebf6ac5c171bb476ce3)
+++ src/GenPoly/GenPoly.cc	(revision 35304009ddd2f96bf13633c8c18b3e3d28cbb924)
@@ -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 Nov 24 15:23:08 2015
-// Update Count     : 11
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 15 16:11:18 2015
+// Update Count     : 13
 //
 
@@ -80,13 +80,13 @@
 	
 	Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
-		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
 			if ( env ) {
 				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
 					return isPolyType( newType, tyVars, env );
-				} // if
 			} // if
+		} // if
 			if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
 				return type;
-			}
+	}
 		} else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
 			if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision ffad73aefa957693bcf94ebf6ac5c171bb476ce3)
+++ src/GenPoly/Lvalue.cc	(revision 35304009ddd2f96bf13633c8c18b3e3d28cbb924)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:41:33 2015
-// Update Count     : 1
+// Last Modified On : Tue Dec 15 15:33:13 2015
+// Update Count     : 3
 //
 
@@ -122,12 +122,15 @@
 			if ( retval && retStmt->get_expr() ) {
 				assert( ! retStmt->get_expr()->get_results().empty() );
-				while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
-					retStmt->set_expr( castExpr->get_arg() );
-					retStmt->get_expr()->set_env( castExpr->get_env() );
-					castExpr->set_env( 0 );
-					castExpr->set_arg( 0 );
-					delete castExpr;
-				} // while
 				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+					// ***** Code Removal ***** because casts may be stripped already
+
+					// strip casts because not allowed to take address of cast
+					// while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
+					// 	retStmt->set_expr( castExpr->get_arg() );
+					// 	retStmt->get_expr()->set_env( castExpr->get_env() );
+					// 	castExpr->set_env( 0 );
+					// 	castExpr->set_arg( 0 );
+					// 	delete castExpr;
+					// } // while
 					retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
 				} else {
