[PATCH] [llgo] Use the object's package to mangle method names, rather than the receiver's package

Peter Collingbourne peter at pcc.me.uk
Mon Dec 15 18:58:33 PST 2014


Hi axw,

If we use the receiver's package, we can end up with identical manglings
for different functions. Consider:

package p
type U struct{}
func (U) f()

package q
import "p"
type T struct { p.U }
func (T) f()

The method set of *T has two synthetic methods named (*T).f(); one forwards to
(T).f(), and the other to (U).f(). Previously, we were distinguishing them
by the receiver's package, and in this case because both methods have the
same receiver, they received the same name.

The methods are correctly distinguished by the package owning the identifier
"f", which is available via f.Object().Pkg().

http://reviews.llvm.org/D6673

Files:
  irgen/typemap.go
  test/irgen/Inputs/mangling-synthetic-p.go
  test/irgen/mangling-dot.go
  test/irgen/mangling-synthetic.go
  test/irgen/mangling.go

Index: irgen/typemap.go
===================================================================
--- irgen/typemap.go
+++ irgen/typemap.go
@@ -659,21 +659,25 @@
 		return b.String()
 	}
 
-	pkg := f.Pkg
-	var pkgobj *types.Package
-	if pkg != nil {
-		pkgobj = pkg.Object
-	} else if f.Signature.Recv() != nil {
-		pkgobj = f.Signature.Recv().Pkg()
-	} else {
+	// Synthetic bound and thunk functions are special cases; they can only be
+	// distinguished using private data that is only exposed via String().
+	if strings.HasSuffix(f.Name(), "$bound") || strings.HasSuffix(f.Name(), "$thunk") {
 		b.WriteString(f.String())
 		return b.String()
 	}
 
+	var pkg *types.Package
+	if f.Pkg != nil {
+		pkg = f.Pkg.Object
+	} else if !f.Object().Exported() {
+		pkg = f.Object().Pkg()
+	}
+
 	if pkg != nil {
-		ctx.manglePackagePath(pkgobj.Path(), &b)
+		ctx.manglePackagePath(pkg.Path(), &b)
 		b.WriteRune('.')
 	}
+
 	if f.Signature.Recv() == nil && f.Name() == "init" {
 		b.WriteString(".import")
 	} else {
Index: test/irgen/Inputs/mangling-synthetic-p.go
===================================================================
--- /dev/null
+++ test/irgen/Inputs/mangling-synthetic-p.go
@@ -0,0 +1,4 @@
+package p
+
+type U struct{}
+func (U) f()
Index: test/irgen/mangling.go
===================================================================
--- /dev/null
+++ test/irgen/mangling.go
@@ -1,7 +0,0 @@
-// RUN: llgo -fgo-pkgpath=llvm.org/llvm -S -emit-llvm -o - %s | FileCheck %s
-
-package llvm
-
-// CHECK: @llvm_org_llvm.F
-func F() {
-}
Index: test/irgen/mangling-synthetic.go
===================================================================
--- /dev/null
+++ test/irgen/mangling-synthetic.go
@@ -0,0 +1,14 @@
+// RUN: llgo -fgo-pkgpath=p -c -o %T/p.o %S/Inputs/mangling-synthetic-p.go
+// RUN: llgo -fgo-pkgpath=q -I %T -S -emit-llvm -o - %s | FileCheck %s
+
+package q
+
+import "p"
+
+// CHECK-DAG: define linkonce_odr void @p.f.N3_q.T(i8*)
+// CHECK-DAG: define linkonce_odr void @p.f.pN3_q.T(i8*)
+type T struct { p.U }
+
+// CHECK-DAG: declare void @q.f.N3_q.T(i8*)
+// CHECK-DAG: define linkonce_odr void @q.f.pN3_q.T(i8*)
+func (T) f()

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D6673.17316.patch
Type: text/x-patch
Size: 2147 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141216/7a480705/attachment.bin>


More information about the llvm-commits mailing list