Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 242d4587f77845aedb54424e5c82b19ce6fc14ab)
+++ src/InitTweak/InitTweak.cc	(revision a465caff623c39b44749b156091c82701114e584)
@@ -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 242d4587f77845aedb54424e5c82b19ce6fc14ab)
+++ src/InitTweak/InitTweak.h	(revision a465caff623c39b44749b156091c82701114e584)
@@ -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 242d4587f77845aedb54424e5c82b19ce6fc14ab)
+++ src/ResolvExpr/Resolver.cc	(revision a465caff623c39b44749b156091c82701114e584)
@@ -550,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/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 242d4587f77845aedb54424e5c82b19ce6fc14ab)
+++ src/SymTab/Autogen.cc	(revision a465caff623c39b44749b156091c82701114e584)
@@ -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 );
@@ -421,9 +421,29 @@
 		makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
 		if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
-
-		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+		else assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
 
 		// body of assignment and copy ctor is the same
 		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 );
@@ -431,4 +451,5 @@
 		declsToAdd.push_back( copyCtorDecl );
 		declsToAdd.push_back( dtorDecl );
+		declsToAdd.splice( declsToAdd.end(), memCtors );
 	}
 
