diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2014-12-16 20:04:55 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2014-12-16 20:04:55 +0000 |
commit | 545e7276a870c60d4d289b72b38e1529dae2acd7 (patch) | |
tree | cfeafd7b8751eac4d296b85e50cd1fad1f33ed1c | |
parent | a4a94f1b552a725ffdbc86b73c8939ea521552f7 (diff) | |
download | bcm5719-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.go | 20 | ||||
-rw-r--r-- | llgo/test/irgen/Inputs/mangling-synthetic-p.go | 4 | ||||
-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.go | 14 |
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() |