From b36aefc95e3d0213f5ee370a91404beed690dc34 Mon Sep 17 00:00:00 2001 From: Zxilly Date: Tue, 2 Jul 2024 04:38:29 +0800 Subject: [PATCH] debug/gosym,cmd/compile/internal/ir: use hash to identify duplicate unexported function --- src/cmd/compile/internal/ir/expr.go | 14 ++++++++++---- src/debug/gosym/pclntab_test.go | 1 + src/debug/gosym/symtab_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index 345828c1638..fe13a840962 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -13,6 +13,8 @@ import ( "fmt" "go/constant" "go/token" + "hash/fnv" + "strconv" ) // An Expr is a Node that can appear as an expression. @@ -1183,17 +1185,21 @@ func MethodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sy fmt.Fprintf(&b, "%-S", recv) } + b.WriteString(".") + b.WriteString(msym.Name) + // A particular receiver type may have multiple non-exported // methods with the same name. To disambiguate them, include a // package qualifier for names that came from a different // package than the receiver type. if !types.IsExported(msym.Name) && msym.Pkg != rpkg { - b.WriteString(".") - b.WriteString(msym.Pkg.Prefix) + b.WriteString("+") + + h := fnv.New32() + h.Write([]byte(msym.Pkg.Prefix)) + b.WriteString(strconv.FormatUint(uint64(h.Sum32()), 16)) } - b.WriteString(".") - b.WriteString(msym.Name) b.WriteString(suffix) return rpkg.LookupBytes(b.Bytes()) } diff --git a/src/debug/gosym/pclntab_test.go b/src/debug/gosym/pclntab_test.go index e380bb5ad73..cffe03d58a0 100644 --- a/src/debug/gosym/pclntab_test.go +++ b/src/debug/gosym/pclntab_test.go @@ -60,6 +60,7 @@ func endtest() { // skipIfNotELF skips the test if we are not running on an ELF system. // These tests open and examine the test binary, and use elf.Open to do so. func skipIfNotELF(t *testing.T) { + t.Helper() switch runtime.GOOS { case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris", "illumos": // OK. diff --git a/src/debug/gosym/symtab_test.go b/src/debug/gosym/symtab_test.go index bb1f267a4df..510c110d16b 100644 --- a/src/debug/gosym/symtab_test.go +++ b/src/debug/gosym/symtab_test.go @@ -10,6 +10,7 @@ import ( ) func assertString(t *testing.T, dsc, out, tgt string) { + t.Helper() if out != tgt { t.Fatalf("Expected: %q Actual: %q for %s", tgt, out, dsc) } @@ -85,3 +86,28 @@ func TestIssue29551(t *testing.T) { assertString(t, fmt.Sprintf("package of %q", tc.sym.Name), tc.sym.PackageName(), tc.pkgName) } } + +func TestIssue66313(t *testing.T) { + tests := []struct { + sym Sym + packageName string + receiverName string + baseName string + }{ + {Sym{Name: "github.com/google/cel-go/parser/gen.(*CELLexer).reset+10c630b8"}, + "github.com/google/cel-go/parser/gen", + "(*CELLexer)", + "reset+10c630b8", + }, + {Sym{Name: "ariga.io/atlas/sql/sqlclient.(*Tx).grabConn+404a5a3"}, + "ariga.io/atlas/sql/sqlclient", + "(*Tx)", + "grabConn+404a5a3"}, + } + + for _, tc := range tests { + assertString(t, fmt.Sprintf("package of %q", tc.sym.Name), tc.sym.PackageName(), tc.packageName) + assertString(t, fmt.Sprintf("receiver of %q", tc.sym.Name), tc.sym.ReceiverName(), tc.receiverName) + assertString(t, fmt.Sprintf("package of %q", tc.sym.Name), tc.sym.BaseName(), tc.baseName) + } +}