summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-12-16 20:04:55 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2014-12-16 20:04:55 +0000
commit545e7276a870c60d4d289b72b38e1529dae2acd7 (patch)
treecfeafd7b8751eac4d296b85e50cd1fad1f33ed1c
parenta4a94f1b552a725ffdbc86b73c8939ea521552f7 (diff)
downloadbcm5719-llvm-545e7276a870c60d4d289b72b38e1529dae2acd7.tar.gz
bcm5719-llvm-545e7276a870c60d4d289b72b38e1529dae2acd7.zip
Use the object's package to mangle method names, rather than the receiver's package
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(). Differential Revision: http://reviews.llvm.org/D6673 llvm-svn: 224357
-rw-r--r--llgo/irgen/typemap.go20
-rw-r--r--llgo/test/irgen/Inputs/mangling-synthetic-p.go4
-rw-r--r--llgo/test/irgen/mangling-dot.go (renamed from llgo/test/irgen/mangling.go)0
-rw-r--r--llgo/test/irgen/mangling-synthetic.go14
4 files changed, 30 insertions, 8 deletions
diff --git a/llgo/irgen/typemap.go b/llgo/irgen/typemap.go
index 29cca053f46..91f4ca4e1c2 100644
--- a/llgo/irgen/typemap.go
+++ b/llgo/irgen/typemap.go
@@ -659,21 +659,25 @@ func (ctx *manglerContext) mangleFunctionName(f *ssa.Function) string {
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 {
diff --git a/llgo/test/irgen/Inputs/mangling-synthetic-p.go b/llgo/test/irgen/Inputs/mangling-synthetic-p.go
new file mode 100644
index 00000000000..c59588a51ba
--- /dev/null
+++ b/llgo/test/irgen/Inputs/mangling-synthetic-p.go
@@ -0,0 +1,4 @@
+package p
+
+type U struct{}
+func (U) f()
diff --git a/llgo/test/irgen/mangling.go b/llgo/test/irgen/mangling-dot.go
index aff73cb8acb..aff73cb8acb 100644
--- a/llgo/test/irgen/mangling.go
+++ b/llgo/test/irgen/mangling-dot.go
diff --git a/llgo/test/irgen/mangling-synthetic.go b/llgo/test/irgen/mangling-synthetic.go
new file mode 100644
index 00000000000..b88e03742b7
--- /dev/null
+++ b/llgo/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()
OpenPOWER on IntegriCloud