Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/GenPoly/Box.cc	(revision 7b3f66b14854533532aad4d0484874f36d0fa385)
@@ -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 Feb  5 16:45:07 2016
-// Update Count     : 286
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue May 03 16:44:47 2016
+// Update Count     : 295
 //
 
@@ -133,5 +133,5 @@
 			Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
  				TypeList typeList( params );
- 				
+
 				// scan scopes for matches to the key
 				for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
@@ -160,5 +160,5 @@
 			virtual Declaration *mutate( UnionDecl *unionDecl );
 		};
-		
+
 		/// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
 		class Pass1 : public PolyMutator {
@@ -208,5 +208,5 @@
 			ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
 			ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
-			
+
 			DeclarationWithType *retval;
 			bool useRetval;
@@ -226,5 +226,5 @@
 			virtual Type *mutate( PointerType *pointerType );
 			virtual Type *mutate( FunctionType *funcType );
-			
+
 		  private:
 			void addAdapters( FunctionType *functionType );
@@ -297,5 +297,5 @@
 			/// Exits the type-variable scope
 			void endTypeScope();
-			
+
 			ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
 			ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
@@ -351,5 +351,5 @@
 		PolyGenericCalculator polyCalculator;
 		Pass3 pass3;
-		
+
 		layoutBuilder.mutateDeclarationList( translationUnit );
 		mutateTranslationUnit/*All*/( translationUnit, pass1 );
@@ -370,5 +370,5 @@
 		return functionDecl;
 	}
-	
+
 	/// Get a list of type declarations that will affect a layout function
 	std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
@@ -380,5 +380,5 @@
 			}
 		}
-		
+
 		return otypeDecls;
 	}
@@ -387,5 +387,5 @@
 	void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
 		BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
-		
+
 		for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
 			TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
@@ -444,5 +444,5 @@
 		return makeCond( ifCond, ifExpr );
 	}
-	
+
 	/// adds an expression to a compound statement
 	void addExpr( CompoundStmt *stmts, Expression *expr ) {
@@ -454,5 +454,5 @@
 		stmts->get_kids().push_back( stmt );
 	}
-	
+
 	Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
 		// do not generate layout function for "empty" tag structs
@@ -467,5 +467,5 @@
 		BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 		PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
-		
+
 		ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
 		layoutFnType->get_parameters().push_back( sizeParam );
@@ -497,5 +497,5 @@
 				addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
 			}
-			
+
 			// place current size in the current offset index
 			addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
@@ -505,5 +505,5 @@
 			// add member size to current size
 			addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
-			
+
 			// take max of member alignment and global alignment
 			addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
@@ -515,9 +515,9 @@
 		return structDecl;
 	}
-	
+
 	Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
 		// do not generate layout function for "empty" tag unions
 		if ( unionDecl->get_members().empty() ) return unionDecl;
-		
+
 		// get parameters that can change layout, exiting early if none
 		std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
@@ -528,5 +528,5 @@
 		BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 		PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
-		
+
 		ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
 		layoutFnType->get_parameters().push_back( sizeParam );
@@ -545,8 +545,8 @@
 			assert( dwt );
 			Type *memberType = dwt->get_type();
-			
+
 			// take max member size and global size
 			addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
-			
+
 			// take max of member alignment and global alignment
 			addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
@@ -558,5 +558,5 @@
 		return unionDecl;
 	}
-	
+
 	////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
 
@@ -619,5 +619,5 @@
 			return 0;
 		}
-		
+
 		/// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
 		/// Only picks assignments where neither parameter is cv-qualified
@@ -631,5 +631,5 @@
 						Type *paramType2 = funType->get_parameters().back()->get_type();
 						if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
-						
+
 						if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
 							Type *baseType1 = pointerType->get_base();
@@ -784,5 +784,6 @@
 						arg++;
 					} else {
-						throw SemanticError( "unbound type variable in application ", appExpr );
+						/// xxx - should this be an assertion?
+						throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr );
 					} // if
 				} // if
@@ -803,5 +804,5 @@
 				passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
 			}
-			
+
 			// add type information args for presently unseen types in parameter list
 			for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
@@ -882,5 +883,5 @@
 			assert( env );
 			Type *concrete = replaceWithConcrete( appExpr, polyType );
-			// add out-parameter for return value	
+			// add out-parameter for return value
 			return addRetParam( appExpr, function, concrete, arg );
 		}
@@ -910,4 +911,5 @@
 				} else if ( arg->get_results().front()->get_isLvalue() ) {
 					// VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
+					// xxx - need to test that this code is still reachable
 					if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
 						commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
@@ -1291,8 +1293,6 @@
 			} else if ( needsAdapter( function, scopeTyVars ) ) {
 				// std::cerr << "needs adapter: ";
-				// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
-				// 	std::cerr << i->first << " ";
-				// }
-				// std::cerr << "\n";
+				// printTyVarMap( std::cerr, scopeTyVars );
+				// std::cerr << *env << std::endl;
 				// change the application so it calls the adapter rather than the passed function
 				ret = applyAdapter( appExpr, function, arg, scopeTyVars );
@@ -1345,6 +1345,9 @@
 				} // if
 			} // if
+			// isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
+			// out of the if condition.
+			bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );
 			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
-			if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
+			if ( polytype || needs ) {
 				Expression *ret = addrExpr->get_arg();
 				delete ret->get_results().front();
@@ -1366,5 +1369,5 @@
 			return new VariableExpr( functionObj );
 		}
-		
+
 		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
 			if ( retval && returnStmt->get_expr() ) {
@@ -1886,5 +1889,5 @@
 				}
 			}
-			
+
 			Type *ret = Mutator::mutate( funcType );
 
@@ -1905,5 +1908,5 @@
 
 					std::list<Expression*> designators;
-					objectDecl->set_init( new SingleInit( alloc, designators ) );
+					objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
 				}
 			}
@@ -1946,5 +1949,5 @@
 			return derefdVar;
 		}
-		
+
 		Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
 			// mutate, exiting early if no longer MemberExpr
@@ -2144,5 +2147,5 @@
 			Type *ty = offsetofExpr->get_type();
 			if ( ! findGeneric( ty ) ) return offsetofExpr;
-			
+
 			if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
 				// replace offsetof expression by index into offset array
Index: src/GenPoly/CopyParams.cc
===================================================================
--- src/GenPoly/CopyParams.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/GenPoly/CopyParams.cc	(revision 7b3f66b14854533532aad4d0484874f36d0fa385)
@@ -5,9 +5,9 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CopyParams.cc -- 
+// CopyParams.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
+// Last Modified By : Rob Schluntz
 // Last Modified On : Tue May 19 07:33:31 2015
 // Update Count     : 1
@@ -29,5 +29,5 @@
 	  public:
 		CopyParams();
-  
+
 		virtual void visit( FunctionDecl *funcDecl );
 		virtual void visit( AddressExpr *addrExpr );
@@ -50,5 +50,5 @@
 		if ( funcDecl->get_statements() ) {
 			funcDecl->get_statements()->accept( *this );
-	
+
 			if ( ! modVars.empty() ) {
 				std::map< std::string, DeclarationWithType* > assignOps;
@@ -57,4 +57,5 @@
 					if ( (*tyVar)->get_kind() == TypeDecl::Any ) {
 						assert( !(*tyVar)->get_assertions().empty() );
+						assert( (*tyVar)->get_assertions().front()->get_name() == "?=?" );
 						assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front();
 					} // if
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/GenPoly/GenPoly.cc	(revision 7b3f66b14854533532aad4d0484874f36d0fa385)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// GenPoly.cc -- 
+// GenPoly.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 15 16:11:18 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon May 02 14:53:33 2016
 // Update Count     : 13
 //
@@ -81,5 +81,5 @@
 		return 0;
 	}
-	
+
 	Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
@@ -112,5 +112,5 @@
 		return 0;
 	}
-	
+
 	Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
 		if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
@@ -146,5 +146,5 @@
 		return isPolyType( type, env );
 	}
-	
+
 	Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
 		int dummy;
@@ -192,4 +192,8 @@
 				if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
 				expr = *untypedExpr->begin_args();
+			} else if ( CommaExpr *commaExpr = dynamic_cast< CommaExpr* >( expr ) ) {
+				// copy constructors insert comma exprs, look at second argument which contains the variable
+				expr = commaExpr->get_arg2();
+				continue;
 			} else break;
 
@@ -209,5 +213,5 @@
 		}
 	}
-	
+
 	void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
 		for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
Index: src/GenPoly/PolyMutator.cc
===================================================================
--- src/GenPoly/PolyMutator.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/GenPoly/PolyMutator.cc	(revision 7b3f66b14854533532aad4d0484874f36d0fa385)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// PolyMutator.cc -- 
+// PolyMutator.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Aug 14 15:28:50 2015
+// Last Modified On : Mon May 02 14:50:58 2016
 // Update Count     : 11
 //
@@ -63,4 +63,5 @@
 				env = expr->get_env();
 			}
+			// xxx - should env be cloned (or moved) onto the result of the mutate?
 			return expr->acceptMutator( *this );
 		} else {
@@ -144,6 +145,6 @@
 		return untypedExpr;
 	}
- 
- 
+
+
 	Initializer *PolyMutator::mutate( SingleInit *singleInit ) {
 		singleInit->set_value( mutateExpression( singleInit->get_value() ) );
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision cb4c607c4212505e28b756e33cdf1030b6bd93e8)
+++ src/GenPoly/Specialize.cc	(revision 7b3f66b14854533532aad4d0484874f36d0fa385)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Jan 20 12:40:33 2016
-// Update Count     : 18
+// Last Modified On : Thu Apr 28 15:17:45 2016
+// Update Count     : 24
 //
 
@@ -41,7 +41,7 @@
 		virtual Expression * mutate( AddressExpr *castExpr );
 		virtual Expression * mutate( CastExpr *castExpr );
-		virtual Expression * mutate( LogicalExpr *logicalExpr );
-		virtual Expression * mutate( ConditionalExpr *conditionalExpr );
-		virtual Expression * mutate( CommaExpr *commaExpr );
+		// virtual Expression * mutate( LogicalExpr *logicalExpr );
+		// virtual Expression * mutate( ConditionalExpr *conditionalExpr );
+		// virtual Expression * mutate( CommaExpr *commaExpr );
 
 	  private:
@@ -142,5 +142,5 @@
 
 	Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
-		assert( ! actual->get_results().empty() );
+		assert( ! actual->get_results().empty() ); // using front, should have this assert
 		if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
 			FunctionType *funType;
@@ -212,15 +212,19 @@
 	}
 
-	Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
-		return logicalExpr;
-	}
-
-	Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
-		return condExpr;
-	}
-
-	Expression * Specialize::mutate( CommaExpr *commaExpr ) {
-		return commaExpr;
-	}
+	// Removing these for now. Richard put these in for some reason, but it's not clear why.
+	// In particular, copy constructors produce a comma expression, and with this code the parts
+	// of that comma expression are not specialized, which causes problems.
+
+	// Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
+	// 	return logicalExpr;
+	// }
+
+	// Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
+	// 	return condExpr;
+	// }
+
+	// Expression * Specialize::mutate( CommaExpr *commaExpr ) {
+	// 	return commaExpr;
+	// }
 } // namespace GenPoly
 
