From: Ian Lance Taylor Date: Fri, 1 Feb 2013 00:23:22 +0000 (+0000) Subject: compiler: Don't emit multiple methods for identical unnamed structs. X-Git-Tag: upstream/12.2.0~71481 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=260f587c3a51252440b07eeaa4794bcb98332c72;p=platform%2Fupstream%2Fgcc.git compiler: Don't emit multiple methods for identical unnamed structs. From-SVN: r195638 --- diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index c0aeb91..7694982 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -4170,6 +4170,11 @@ Struct_field::is_field_name(const std::string& name) const // 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 @@ Struct_type::finalize_methods(Gogo* gogo) { 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 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 --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index ba918c9..3922a63 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2184,6 +2184,12 @@ class Struct_type : public Type 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 {