compiler: don't export function descriptors for unexported names

They aren't needed, and could potentially cause unlikely symbol name
collisions.  Also, the runtime package's reference to main could cause
the runtime package to define main.main..f, which could also be
defined in the main package if it does something like fmt.Print(main).
That will normally work but will fail with a multiple symbol
definition error when using -static-libgo.

Change-Id: Ie8549c354688d264c65b60c5855d41eff1ab0ee7
Reviewed-on: https://go-review.googlesource.com/93656
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/go/expressions.cc b/go/expressions.cc
index f50de0a..9792faa 100644
--- a/go/expressions.cc
+++ b/go/expressions.cc
@@ -1330,9 +1330,24 @@
   else
     {
       Location bloc = Linemap::predeclared_location();
+
+      // The runtime package has hash/equality functions that are
+      // referenced by type descriptors outside of the runtime, so the
+      // function descriptors must be visible even though they are not
+      // exported.
+      bool is_exported_runtime = false;
+      if (gogo->compiling_runtime()
+	  && gogo->package_name() == "runtime"
+	  && (no->name().find("hash") != std::string::npos
+	      || no->name().find("equal") != std::string::npos))
+	is_exported_runtime = true;
+
       bool is_hidden = ((no->is_function()
 			 && no->func_value()->enclosing() != NULL)
+			|| (Gogo::is_hidden_name(no->name())
+			    && !is_exported_runtime)
 			|| Gogo::is_thunk(no));
+
       bvar = context->backend()->immutable_struct(var_name, asm_name,
                                                   is_hidden, false,
 						  btype, bloc);