cmd/compile: have all or no parameter named in exported signatures

Binary export format only.

Make sure we don't accidentally export an unnamed parameter
in signatures which expect all named parameters; otherwise
we crash during import. Appears to happen for _ (blank)
parameter names, as observed in method signatures such as
the one at: x/tools/godoc/analysis/analysis.go:76.

Fixes #15470.

TBR=mdempsky

Change-Id: I1b1184bf08c4c09d8a46946539c4b8c341acdb84
Reviewed-on: https://go-review.googlesource.com/22543
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/src/cmd/compile/internal/gc/bexport.go b/src/cmd/compile/internal/gc/bexport.go
index 9c5d8bd..20c1aeb 100644
--- a/src/cmd/compile/internal/gc/bexport.go
+++ b/src/cmd/compile/internal/gc/bexport.go
@@ -819,19 +819,30 @@
 	}
 	p.typ(t)
 	if n > 0 {
-		p.string(parName(q, numbered))
-		// Because of (re-)exported inlined functions
-		// the importpkg may not be the package to which this
-		// function (and thus its parameter) belongs. We need to
-		// supply the parameter package here. We need the package
-		// when the function is inlined so we can properly resolve
-		// the name.
-		// TODO(gri) This is compiler-specific. Try using importpkg
-		// here and then update the symbols if we find an inlined
-		// body only. Otherwise, the parameter name is ignored and
-		// the package doesn't matter. This would remove an int
-		// (likely 1 byte) for each named parameter.
-		p.pkg(q.Sym.Pkg)
+		if name := parName(q, numbered); name != "" {
+			p.string(name)
+			// Because of (re-)exported inlined functions
+			// the importpkg may not be the package to which this
+			// function (and thus its parameter) belongs. We need to
+			// supply the parameter package here. We need the package
+			// when the function is inlined so we can properly resolve
+			// the name.
+			// TODO(gri) This is compiler-specific. Try using importpkg
+			// here and then update the symbols if we find an inlined
+			// body only. Otherwise, the parameter name is ignored and
+			// the package doesn't matter. This would remove an int
+			// (likely 1 byte) for each named parameter.
+			p.pkg(q.Sym.Pkg)
+		} else {
+			// Sometimes we see an empty name even for n > 0.
+			// This appears to happen for interface methods
+			// with _ (blank) parameter names. Make sure we
+			// have a proper name and package so we don't crash
+			// during import (see also issue #15470).
+			// TODO(gri) review parameter encoding
+			p.string("_")
+			p.pkg(localpkg)
+		}
 	}
 	// TODO(gri) This is compiler-specific (escape info).
 	// Move into compiler-specific section eventually?