This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
gccgo patch committed: Don't emit methods for identical unnamed structs
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Thu, 31 Jan 2013 16:23:23 -0800
- Subject: gccgo patch committed: Don't emit methods for identical unnamed structs
When a source file has multiple identical unnamed structs, and those
structs have methods, gccgo would emit multiple copies of the methods.
That would be bad because each copy would have the same name, causing an
assembler error about multiply defined symbols. This patch fixes the
problem. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.
Ian
diff -r 73fde5ee3282 go/types.cc
--- a/go/types.cc Thu Jan 31 15:11:34 2013 -0800
+++ b/go/types.cc Thu Jan 31 16:20:32 2013 -0800
@@ -4170,6 +4170,11 @@
// Class Struct_type.
+// A hash table used to find identical unnamed structs so that they
+// share method tables.
+
+Struct_type::Identical_structs Struct_type::identical_structs;
+
// Traversal.
int
@@ -4596,6 +4601,21 @@
{
if (this->all_methods_ != NULL)
return;
+
+ // It is possible to have multiple identical structs that have
+ // methods. We want them to share method tables. Otherwise we will
+ // emit identical methods more than once, which is bad since they
+ // will even have the same names.
+ std::pair<Identical_structs::iterator, bool> ins =
+ Struct_type::identical_structs.insert(std::make_pair(this, this));
+ if (!ins.second)
+ {
+ // An identical struct was already entered into the hash table.
+ // Note that finalize_methods is, fortunately, not recursive.
+ this->all_methods_ = ins.first->second->all_methods_;
+ return;
+ }
+
Type::finalize_methods(gogo, this, this->location_, &this->all_methods_);
}
diff -r 73fde5ee3282 go/types.h
--- a/go/types.h Thu Jan 31 15:11:34 2013 -0800
+++ b/go/types.h Thu Jan 31 16:20:32 2013 -0800
@@ -2184,6 +2184,12 @@
do_export(Export*) const;
private:
+ // Used to merge method sets of identical unnamed structs.
+ typedef Unordered_map_hash(Struct_type*, Struct_type*, Type_hash_identical,
+ Type_identical) Identical_structs;
+
+ static Identical_structs identical_structs;
+
// Used to avoid infinite loops in field_reference_depth.
struct Saw_named_type
{