Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/InitTweak/InitTweak.cc	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -291,9 +291,16 @@
 	}
 
+	namespace {
+		template <typename Predicate>
+		bool allofCtorDtor( Statement * stmt, const Predicate & pred ) {
+			std::list< Expression * > callExprs;
+			collectCtorDtorCalls( stmt, callExprs );
+			// if ( callExprs.empty() ) return false; // xxx - do I still need this check?
+			return std::all_of( callExprs.begin(), callExprs.end(), pred);
+		}
+	}
+
 	bool isIntrinsicSingleArgCallStmt( Statement * stmt ) {
-		std::list< Expression * > callExprs;
-		collectCtorDtorCalls( stmt, callExprs );
-		// if ( callExprs.empty() ) return false; // xxx - do I still need this check?
-		return std::all_of( callExprs.begin(), callExprs.end(), []( Expression * callExpr ){
+		return allofCtorDtor( stmt, []( Expression * callExpr ){
 			if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
 				assert( ! appExpr->get_function()->get_results().empty() );
@@ -303,4 +310,10 @@
 			}
 			return false;
+		});
+	}
+
+	bool isIntrinsicCallStmt( Statement * stmt ) {
+		return allofCtorDtor( stmt, []( Expression * callExpr ) {
+			return isIntrinsicCallExpr( callExpr );
 		});
 	}
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/InitTweak/InitTweak.h	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -41,5 +41,8 @@
 	/// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
 	/// Currently has assertions that make it less than fully general.
-	bool isIntrinsicSingleArgCallStmt( Statement * expr );
+	bool isIntrinsicSingleArgCallStmt( Statement * stmt );
+
+	/// True if stmt is a call statement where the function called is intrinsic.
+	bool isIntrinsicCallStmt( Statement * stmt );
 
 	/// get all Ctor/Dtor call expressions from a Statement
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/ResolvExpr/Resolver.cc	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -446,7 +446,18 @@
 		} else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
 			resolveAggrInit( st->get_baseStruct(), iter, end );
-		} else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) {
+		} else if ( UnionInstType * st = dynamic_cast< UnionInstType * >( initContext ) ) {
 			resolveAggrInit( st->get_baseUnion(), iter, end );
+		} else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
+			Type * base = tt->get_baseType()->get_base();
+			if ( base ) {
+				// know the implementation type, so try using that as the initContext
+				initContext = base;
+				visit( listInit );
+			} else {
+				// missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
+				Visitor::visit( listInit );
+			}
 		} else {
+			assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) );
 			// basic types are handled here
 			Visitor::visit( listInit );
@@ -539,14 +550,19 @@
 		}
 
-		// xxx - todo
-		// if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
-		// 	// can reduce the constructor down to a SingleInit using the
-		// 	// second argument from the ctor call
-		// }
-
 		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
 			delete ctorInit->get_dtor();
 			ctorInit->set_dtor( NULL );
 		}
+
+		// xxx - todo -- what about arrays?
+		// if ( dtor == NULL && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
+		// 	// can reduce the constructor down to a SingleInit using the
+		// 	// second argument from the ctor call, since
+		// 	delete ctorInit->get_ctor();
+		// 	ctorInit->set_ctor( NULL );
+
+		// 	Expression * arg =
+		// 	ctorInit->set_init( new SingleInit( arg ) );
+		// }
 	}
 } // namespace ResolvExpr
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TypeEnvironment.cc -- 
+// TypeEnvironment.cc --
 //
 // Author           : Richard C. Bilson
@@ -23,4 +23,53 @@
 
 namespace ResolvExpr {
+	// adding this comparison operator significantly improves assertion resolution run time for
+	// some cases. The current resolution algorithm's speed partially depends on the order of
+	// assertions. Assertions which have fewer possible matches should appear before
+	// assertions which have more possible matches. This seems to imply that this could
+	// be further improved by providing an indexer as an additional argument and ordering based
+	// on the number of matches of the same kind (object, function) for the names of the
+	// declarations.
+	//
+	// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
+	bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) {
+			// Objects are always less than functions
+			if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {
+				if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {
+					// objects are ordered by name then type pointer, in that order
+					int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );
+					return cmp < 0 ||
+						( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );
+				} else {
+					return true;
+				}
+			} else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {
+				if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {
+					// functions are ordered by name, # parameters, # returnVals, type pointer in that order
+					FunctionType * ftype1 = funcDecl1->get_functionType();
+					FunctionType * ftype2 = funcDecl2->get_functionType();
+					int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();
+					int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();
+					if ( numThings1 < numThings2 ) return true;
+					if ( numThings1 > numThings2 ) return false;
+
+					// if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;
+					// else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;
+					// // same number of parameters
+					// if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;
+					// else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;
+					// same number of return vals
+					// int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );
+					// if ( cmp < 0 ) return true;
+					// else if ( cmp > 0 ) return false;
+					// // same name
+					return ftype1 < ftype2;
+				} else {
+					return false;
+				}
+			} else {
+				assert( false );
+			}
+		}
+
 	void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
 		for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/ResolvExpr/TypeEnvironment.h	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TypeEnvironment.h -- 
+// TypeEnvironment.h --
 //
 // Author           : Richard C. Bilson
@@ -28,5 +28,8 @@
 
 namespace ResolvExpr {
-	typedef std::map< DeclarationWithType*, bool > AssertionSet;
+	struct AssertCompare {
+		bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 );
+	};
+	typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet;
 	typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
 
@@ -39,5 +42,5 @@
 		bool allowWidening;
 		TypeDecl::Kind kind;
-  
+
 		void initialize( const EqvClass &src, EqvClass &dest );
 		EqvClass();
@@ -62,5 +65,5 @@
 		void extractOpenVars( OpenVarSet &openVars ) const;
 		TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
-  
+
 		typedef std::list< EqvClass >::iterator iterator;
 		iterator begin() { return env.begin(); }
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/ResolvExpr/Unify.cc	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -484,13 +484,13 @@
 		FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
 		if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
-
-			if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
-
-				if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
-
-					markAssertions( haveAssertions, needAssertions, functionType );
-					markAssertions( haveAssertions, needAssertions, otherFunction );
-
-					result = true;
+			if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) {
+				if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
+					if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
+
+						markAssertions( haveAssertions, needAssertions, functionType );
+						markAssertions( haveAssertions, needAssertions, otherFunction );
+
+						result = true;
+					} // if
 				} // if
 			} // if
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/SymTab/Autogen.cc	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -68,5 +68,5 @@
 		copy->get_args().push_back( new VariableExpr( dstParam ) );
 		copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
-		copy->get_args().push_back( new SizeofExpr( unionType ) );
+		copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
 
 		*out++ = new ExprStmt( noLabels, copy );
@@ -420,8 +420,30 @@
 		copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
 
+		// create a constructor which takes the first member type as a parameter.
+		// for example, for Union A { int x; double y; }; generate
+		// void ?{}(A *, int)
+		// This is to mimic C's behaviour which initializes the first member of the union.
+		std::list<Declaration *> memCtors;
+		for ( Declaration * member : aggregateDecl->get_members() ) {
+			if ( DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ) ) {
+				ObjectDecl * srcParam = new ObjectDecl( "src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 );
+
+				FunctionType * memCtorType = ctorType->clone();
+				memCtorType->get_parameters().push_back( srcParam );
+				FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType, new CompoundStmt( noLabels ), true, false );
+				ctor->fixUniqueId();
+
+				makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( ctor->get_statements()->get_kids() ) );
+				memCtors.push_back( ctor );
+				// only generate a ctor for the first field
+				break;
+			}
+		}
+
 		declsToAdd.push_back( assignDecl );
 		declsToAdd.push_back( ctorDecl );
 		declsToAdd.push_back( copyCtorDecl );
 		declsToAdd.push_back( dtorDecl );
+		declsToAdd.splice( declsToAdd.end(), memCtors );
 	}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/SymTab/Validate.cc	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -162,5 +162,7 @@
 
 		typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
+		typedef std::map< std::string, TypeDecl * > TypeDeclMap;
 		TypedefMap typedefNames;
+		TypeDeclMap typedeclNames;
 		int scopeLevel;
 	};
@@ -521,4 +523,8 @@
 			delete typeInst;
 			return ret;
+		} else {
+			TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
+			assert( base != typedeclNames.end() );
+			typeInst->set_baseType( base->second->clone() );
 		} // if
 		return typeInst;
@@ -565,4 +571,6 @@
 			typedefNames.erase( i ) ;
 		} // if
+
+		typedeclNames[ typeDecl->get_name() ] = typeDecl;
 		return typeDecl;
 	}
Index: src/tests/.expect/32/extension.txt
===================================================================
--- src/tests/.expect/32/extension.txt	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/tests/.expect/32/extension.txt	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -70,4 +70,9 @@
 static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){
 }
+static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){
+    void *_tmp_cp_ret2;
+    ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));
+    ((void)(_tmp_cp_ret2) /* ^?{} */);
+}
 __extension__ enum E {
     __R__C2eE_1,
@@ -89,7 +94,7 @@
     __extension__ int __c__i_2;
     ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2)));
-    int _tmp_cp_ret2;
-    ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    int _tmp_cp_ret3;
+    ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));
+    ((void)(_tmp_cp_ret3) /* ^?{} */);
     ((void)__extension__ sizeof(3));
     ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
Index: src/tests/.expect/64/extension.txt
===================================================================
--- src/tests/.expect/64/extension.txt	(revision bd9f8be059b946b3b4d115471e2dbf44f7813fd2)
+++ src/tests/.expect/64/extension.txt	(revision f87408e9321946317a275df9cd75d82077dda957)
@@ -70,4 +70,9 @@
 static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){
 }
+static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){
+    void *_tmp_cp_ret2;
+    ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));
+    ((void)(_tmp_cp_ret2) /* ^?{} */);
+}
 __extension__ enum E {
     __R__C2eE_1,
@@ -89,7 +94,7 @@
     __extension__ int __c__i_2;
     ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2)));
-    int _tmp_cp_ret2;
-    ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    int _tmp_cp_ret3;
+    ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));
+    ((void)(_tmp_cp_ret3) /* ^?{} */);
     ((void)__extension__ sizeof(3));
     ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
