The Go frontend was using the wrong name for an method generated for an embedded imported type with an unexported method. This is a kind of unlikely case, but it could lead to name collisions in the assembly code. I added a test case to the master Go repository, and it will come into the gccgo testsuite in due course. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.8 branch.
Ian
diff -r ef1b48bc00bf go/gogo-tree.cc --- a/go/gogo-tree.cc Wed Sep 18 14:51:20 2013 -0700 +++ b/go/gogo-tree.cc Wed Sep 18 16:13:42 2013 -0700 @@ -1009,6 +1009,16 @@ else package_name = this->package_->package_name(); + // Note that this will be misleading if this is an unexported + // method generated for an embedded imported type. In that case + // the unexported method should have the package name of the + // package from which it is imported, but we are going to give + // it our package name. Fixing this would require knowing the + // package name, but we only know the package path. It might be + // better to use package paths here anyhow. This doesn't affect + // the assembler code, because we always set that name in + // Function::get_or_make_decl anyhow. FIXME. + decl_name = package_name + '.' + Gogo::unpack_hidden_name(this->name_); Function_type* fntype; @@ -1317,7 +1327,21 @@ || this->type_->is_method()) { TREE_PUBLIC(decl) = 1; - std::string asm_name = gogo->pkgpath_symbol(); + std::string pkgpath = gogo->pkgpath_symbol(); + if (this->type_->is_method() + && Gogo::is_hidden_name(no->name()) + && Gogo::hidden_name_pkgpath(no->name()) != gogo->pkgpath()) + { + // This is a method we created for an unexported + // method of an imported embedded type. We need to + // use the pkgpath of the imported package to avoid + // a possible name collision. See bug478 for a test + // case. + pkgpath = Gogo::hidden_name_pkgpath(no->name()); + pkgpath = Gogo::pkgpath_for_symbol(pkgpath); + } + + std::string asm_name = pkgpath; asm_name.append(1, '.'); asm_name.append(Gogo::unpack_hidden_name(no->name())); if (this->type_->is_method())