Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 148611679a2e1e25cd25158649aa1734a3b0ec37)
+++ src/SymTab/Validate.cc	(revision 9facf3b0994f0b1e51acecc9de03cae8628dc5fa)
@@ -61,9 +61,10 @@
 #include <algorithm>
 #include "InitTweak/InitTweak.h"
+#include "CodeGen/CodeGenerator.h"
 
 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
 
 namespace SymTab {
-	class HoistStruct : public Visitor {
+	class HoistStruct final : public Visitor {
 	  public:
 		/// Flattens nested struct types
@@ -87,7 +88,13 @@
 
 	/// Fix return types so that every function returns exactly one value
-	class ReturnTypeFixer : public Visitor {
+	class ReturnTypeFixer final : public Visitor {
 	  public:
+
+		typedef Visitor Parent;
+		using Parent::visit;
+
 		static void fix( std::list< Declaration * > &translationUnit );
+
+		virtual void visit( FunctionDecl * functionDecl );
 
 		virtual void visit( FunctionType * ftype );
@@ -95,5 +102,5 @@
 
 	/// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
-	class EnumAndPointerDecayPass : public Visitor {
+	class EnumAndPointerDecayPass final : public Visitor {
 		typedef Visitor Parent;
 		virtual void visit( EnumDecl *aggregateDecl );
@@ -762,7 +769,20 @@
 	}
 
+	void ReturnTypeFixer::visit( FunctionDecl * functionDecl ) {
+		Parent::visit( functionDecl );
+		FunctionType * ftype = functionDecl->get_functionType();
+		std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
+		assertf( retVals.size() == 0 || retVals.size() == 1, "Function %s has too many return values: %d", functionDecl->get_name().c_str(), retVals.size() );
+		if ( retVals.size() == 1 ) {
+			// ensure all function return values have a name - use the name of the function to disambiguate (this also provides a nice bit of help for debugging)
+			// ensure other return values have a name
+			DeclarationWithType * ret = retVals.front();
+			if ( ret->get_name() == "" ) {
+				ret->set_name( toString( "_retval_", CodeGen::genName( functionDecl ) ) );
+			}
+		}
+	}
+
 	void ReturnTypeFixer::visit( FunctionType * ftype ) {
-		static UniqueName tempNamer( "_retval" );
-
 		// xxx - need to handle named return values - this information needs to be saved somehow
 		// so that resolution has access to the names.
@@ -774,14 +794,8 @@
 			TupleType * tupleType = safe_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
 			// ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
-			ObjectDecl * newRet = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
+			ObjectDecl * newRet = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
 			deleteAll( retVals );
 			retVals.clear();
 			retVals.push_back( newRet );
-		} else if ( retVals.size() == 1 ) {
-			// ensure other return values have a name
-			DeclarationWithType * ret = retVals.front();
-			if ( ret->get_name() == "" ) {
-				ret->set_name( tempNamer.newName() );
-			}
 		}
 	}
