Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/Box.cc	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -27,6 +27,7 @@
 #include "Box.h"
 #include "DeclMutator.h"
+#include "Lvalue.h"
+#include "FindFunction.h"
 #include "PolyMutator.h"
-#include "FindFunction.h"
 #include "ScopedSet.h"
 #include "ScrubTyVars.h"
@@ -204,5 +205,5 @@
 		};
 
-		/// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
+		/// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
 		class Pass3 final : public PolyMutator {
 		  public:
@@ -212,4 +213,6 @@
 			using PolyMutator::mutate;
 			virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
+			virtual Declaration *mutate( StructDecl *structDecl ) override;
+			virtual Declaration *mutate( UnionDecl *unionDecl ) override;
 			virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
 			virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
@@ -757,16 +760,13 @@
 			assertf( arg->has_result(), "arg does not have result: %s", toString( arg ).c_str() );
 			if ( isPolyType( param, exprTyVars ) ) {
-				if ( isPolyType( arg->get_result() ) ) {
+				Type * newType = arg->get_result()->clone();
+				if ( env ) env->apply( newType );
+				std::auto_ptr<Type> manager( newType );
+				if ( isPolyType( newType ) ) {
 					// if the argument's type is polymorphic, we don't need to box again!
 					return;
-				} else if ( arg->get_result()->get_lvalue() ) {  // xxx - is this still right??
-				// xxx - dynamic_cast<ReferenceType *>( arg->get_result() )??
-					// 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() ) );
-					} else {
-						arg = new AddressExpr( arg );
-					}
+				} else if ( arg->get_result()->get_lvalue() ) {
+					// argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
+					arg =  generalizedLvalue( new AddressExpr( arg ) );
 					if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
 						// silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
@@ -1760,5 +1760,5 @@
 
 		Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) {
-			Type *ty = sizeofExpr->get_type();
+			Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
 			if ( findGeneric( ty ) ) {
 				Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
@@ -1770,5 +1770,5 @@
 
 		Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) {
-			Type *ty = alignofExpr->get_type();
+			Type *ty = alignofExpr->get_isType() ? alignofExpr->get_type() : alignofExpr->get_expr()->get_result();
 			if ( findGeneric( ty ) ) {
 				Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
@@ -1880,4 +1880,19 @@
 		}
 
+		/// Strips the members from a generic aggregate
+		void stripGenericMembers(AggregateDecl* decl) {
+			if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
+		}
+
+		Declaration *Pass3::mutate( StructDecl *structDecl ) {
+			stripGenericMembers( structDecl );
+			return structDecl;
+		}
+
+		Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
+			stripGenericMembers( unionDecl );
+			return unionDecl;
+		}
+
 		TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
 //   Initializer *init = 0;
Index: src/GenPoly/Box.h
===================================================================
--- src/GenPoly/Box.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/Box.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Nov 19 17:24:01 2015
-// Update Count     : 5
+// Last Modified On : Sat Jul 22 09:23:52 2017
+// Update Count     : 6
 //
 
-#ifndef _BOX_H
-#define _BOX_H
+#pragma once
 
 #include <list>
@@ -25,6 +24,4 @@
 } // namespace GenPoly
 
-#endif // _BOX_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/CopyParams.h
===================================================================
--- src/GenPoly/CopyParams.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/CopyParams.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:34:25 2015
-// Update Count     : 1
+// Last Modified On : Sat Jul 22 09:23:09 2017
+// Update Count     : 2
 //
 
-#ifndef _COPYPARAMS_H
-#define _COPYPARAMS_H
+#pragma once
 
 #include "SynTree/SynTree.h"
@@ -24,6 +23,4 @@
 } // namespace GenPoly
 
-#endif // _COPYPARAMS_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/DeclMutator.h
===================================================================
--- src/GenPoly/DeclMutator.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/DeclMutator.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Fri Nov 27 14:44:00 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:39:01 2016
-// Update Count     : 2
+// Last Modified On : Sat Jul 22 09:21:12 2017
+// Update Count     : 4
 //
 
-#ifndef _DECLMUTATOR_H
-#define _DECLMUTATOR_H
+#pragma once
 
 #include <list>
@@ -27,5 +26,5 @@
 	/// Mutates a list of declarations, providing a means of adding new declarations into the list
 	class DeclMutator : public Mutator {
-	public:
+	  public:
 		typedef Mutator Parent;
 
@@ -50,5 +49,5 @@
 		/// Called on exit from a scope; overriders should call this as a super-class call
 		virtual void doEndScope();
-	protected:
+	  protected:
 		/// Mutate a statement that forms its own scope
 		Statement* mutateStatement( Statement *stmt );
@@ -59,5 +58,5 @@
 		/// Add a declaration to the list to be added after the current position
 		void addDeclarationAfter( Declaration* decl );
-	private:
+	  private:
 		/// A stack of declarations to add before the current declaration or statement
 		std::vector< std::list< Declaration* > > declsToAdd;
@@ -67,6 +66,4 @@
 } // namespace
 
-#endif // _DECLMUTATOR_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/ErasableScopedMap.h
===================================================================
--- src/GenPoly/ErasableScopedMap.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/ErasableScopedMap.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -9,11 +9,10 @@
 // Author           : Aaron B. Moss
 // Created On       : Wed Dec 2 11:37:00 2015
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Wed Dec 2 11:37:00 2015
-// Update Count     : 1
-//
-
-#ifndef _ERASABLESCOPEDMAP_H
-#define _ERASABLESCOPEDMAP_H
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Jul 22 09:23:24 2017
+// Update Count     : 2
+//
+
+#pragma once
 
 #include <cassert>
@@ -278,6 +277,4 @@
 } // namespace GenPoly
 
-#endif // _ERASABLESCOPEDMAP_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/FindFunction.h
===================================================================
--- src/GenPoly/FindFunction.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/FindFunction.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:36:35 2015
-// Update Count     : 1
+// Last Modified On : Sat Jul 22 09:23:36 2017
+// Update Count     : 2
 //
 
-#ifndef FINDFUNCTION_H
-#define FINDFUNCTION_H
+#pragma once
 
 #include "SynTree/SynTree.h"
@@ -29,6 +28,4 @@
 } // namespace GenPoly
 
-#endif // FINDFUNCTION_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/GenPoly.h
===================================================================
--- src/GenPoly/GenPoly.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/GenPoly.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -9,11 +9,10 @@
 // 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:24:38 2015
-// Update Count     : 6
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Jul 22 09:22:57 2017
+// Update Count     : 7
 //
 
-#ifndef GENPOLY_H
-#define GENPOLY_H
+#pragma once
 
 #include <string>
@@ -111,6 +110,4 @@
 } // namespace GenPoly
 
-#endif // GENPOLY_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/InstantiateGeneric.h
===================================================================
--- src/GenPoly/InstantiateGeneric.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/InstantiateGeneric.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -9,11 +9,10 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu Aug 04 18:33:00 2016
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Thu Aug 04 18:33:00 2016
-// Update Count     : 1
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Jul 22 09:22:42 2017
+// Update Count     : 2
 //
 
-#ifndef _INSTANTIATEGENERIC_H
-#define _INSTANTIATEGENERIC_H
+#pragma once
 
 #include "SynTree/SynTree.h"
@@ -26,6 +25,4 @@
 } // namespace GenPoly
 
-#endif // _INSTANTIATEGENERIC_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/Lvalue.cc	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -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 ); } );
 		}
 
Index: src/GenPoly/Lvalue.h
===================================================================
--- src/GenPoly/Lvalue.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/Lvalue.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:42:09 2015
-// Update Count     : 1
+// Last Modified On : Sat Jul 22 09:21:59 2017
+// Update Count     : 2
 //
 
-#ifndef _LVALUE_H
-#define _LVALUE_H
+#pragma once
 
 #include <list>
@@ -27,7 +26,8 @@
 	/// true after reference types have been eliminated from the source code. After this point, reference types should not be added to the AST.
 	bool referencesPermissable();
+
+	/// applies transformations that allow GCC to accept more complicated lvalue expressions, e.g. &(a, b)
+	Expression * generalizedLvalue( Expression * expr );
 } // namespace GenPoly
-
-#endif // _LVALUE_H
 
 // Local Variables: //
Index: src/GenPoly/PolyMutator.h
===================================================================
--- src/GenPoly/PolyMutator.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/PolyMutator.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:39:41 2016
-// Update Count     : 6
+// Last Modified On : Sat Jul 22 09:20:31 2017
+// Update Count     : 7
 //
 
-#ifndef _POLYMUTATOR_H
-#define _POLYMUTATOR_H
+#pragma once
 
 #include <map>
@@ -66,6 +65,4 @@
 } // namespace
 
-#endif // _POLYMUTATOR_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/ScopedSet.h
===================================================================
--- src/GenPoly/ScopedSet.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/ScopedSet.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -9,11 +9,10 @@
 // Author           : Aaron B. Moss
 // Created On       : Thu Dec 3 11:51:00 2015
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Thu Dec 3 11:51:00 2015
-// Update Count     : 1
-//
-
-#ifndef _SCOPEDSET_H
-#define _SCOPEDSET_H
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Jul 22 09:22:17 2017
+// Update Count     : 2
+//
+
+#pragma once
 
 #include <iterator>
@@ -247,6 +246,4 @@
 } // namespace GenPoly
 
-#endif // _SCOPEDSET_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/ScrubTyVars.h
===================================================================
--- src/GenPoly/ScrubTyVars.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/ScrubTyVars.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:48:14 2015
-// Update Count     : 1
+// Last Modified On : Sat Jul 22 09:21:47 2017
+// Update Count     : 2
 //
 
-#ifndef _SCRUBTYVARS_H
-#define _SCRUBTYVARS_H
+#pragma once
 
 #include <string>
@@ -95,6 +94,4 @@
 } // namespace GenPoly
 
-#endif // _SCRUBTYVARS_H
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/GenPoly/Specialize.h
===================================================================
--- src/GenPoly/Specialize.h	(revision 8499c707578896a47b4447c47a6198352ac005a7)
+++ src/GenPoly/Specialize.h	(revision 36a5a77ac8984b7504f7dad9906fa0e218809bfe)
@@ -10,10 +10,9 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:53:58 2015
-// Update Count     : 1
+// Last Modified On : Sat Jul 22 09:22:31 2017
+// Update Count     : 2
 //
 
-#ifndef _SPECIALIZE_H
-#define _SPECIALIZE_H
+#pragma once
 
 #include <list>
@@ -26,6 +25,4 @@
 } // namespace GenPoly
 
-#endif // _SPECIALIZE_H
-
 // Local Variables: //
 // tab-width: 4 //
