Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 6137fbb8754ddae70e06461364ee568113aaa3e3)
+++ src/InitTweak/GenInit.cc	(revision bd7e60918ad2d7fa73046569632b064782dac72e)
@@ -129,9 +129,14 @@
 		// hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
 		// is being returned
-		if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
+		if ( returnStmt->expr && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
 			// explicitly construct the return value using the return expression and the retVal object
 			assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
 
-			stmtsToAddBefore.push_back( genCtorDtor( "?{}", dynamic_cast< ObjectDecl *>( returnVals.front() ), returnStmt->get_expr() ) );
+			ObjectDecl * retVal = strict_dynamic_cast< ObjectDecl * >( returnVals.front() );
+			if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( returnStmt->expr ) ) {
+				// return statement has already been mutated - don't need to do it again
+				if ( varExpr->var == retVal ) return;
+			}
+			stmtsToAddBefore.push_back( genCtorDtor( "?{}", retVal, returnStmt->get_expr() ) );
 
 			// return the retVal object
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 6137fbb8754ddae70e06461364ee568113aaa3e3)
+++ src/SymTab/Validate.cc	(revision bd7e60918ad2d7fa73046569632b064782dac72e)
@@ -153,4 +153,6 @@
 		void previsit( ObjectDecl * object );
 		void previsit( FunctionDecl * func );
+		void previsit( StructDecl * aggrDecl );
+		void previsit( UnionDecl * aggrDecl );
 	};
 
@@ -270,13 +272,14 @@
 		acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
 		VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
+		ReturnChecker::checkFunctionReturns( translationUnit );
+		InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
 		Concurrency::applyKeywords( translationUnit );
+		acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
 		autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
 		Concurrency::implementMutexFuncs( translationUnit );
 		Concurrency::implementThreadStarter( translationUnit );
-		ReturnChecker::checkFunctionReturns( translationUnit );
 		mutateAll( translationUnit, compoundliteral );
-		acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines
 		ArrayLength::computeLength( translationUnit );
-		acceptAll( translationUnit, finder );
+		acceptAll( translationUnit, finder ); // xxx - remove this pass soon
 		mutateAll( translationUnit, labelAddrFixer );
 	}
@@ -620,4 +623,12 @@
 	}
 
+	void ForallPointerDecay::previsit( StructDecl * aggrDecl ) {
+		forallFixer( aggrDecl->parameters, aggrDecl );
+	}
+
+	void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) {
+		forallFixer( aggrDecl->parameters, aggrDecl );
+	}
+
 	void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
 		PassVisitor<ReturnChecker> checker;
