This patch to the Go frontend adds a COMPARE_ALIASES flag for type compare and hash functions. Normally aliases compare as identical to the underlying type. The new COMPARE_ALIASES flag lets them compare (and hash) differently. This will be used by later work. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 265296) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -9c985ce6f76dd65b8eb0e4b03c09ad0100712e04 +6f4bce815786ff3803741355f7f280e4e2c89668 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/types.cc =================================================================== --- gcc/go/gofrontend/types.cc (revision 265296) +++ gcc/go/gofrontend/types.cc (working copy) @@ -349,9 +349,16 @@ Type::are_identical(const Type* t1, cons return (flags & COMPARE_ERRORS) == 0 ? true : t1 == t2; } - // Skip defined forward declarations. Ignore aliases. - t1 = t1->unalias(); - t2 = t2->unalias(); + // Skip defined forward declarations. + t1 = t1->forwarded(); + t2 = t2->forwarded(); + + if ((flags & COMPARE_ALIASES) == 0) + { + // Ignore aliases. + t1 = t1->unalias(); + t2 = t2->unalias(); + } if (t1 == t2) return true; @@ -923,12 +930,17 @@ Type::copy_expressions() unsigned int Type::hash_for_method(Gogo* gogo, int flags) const { - if (this->named_type() != NULL && this->named_type()->is_alias()) - return this->named_type()->real_type()->hash_for_method(gogo, flags); - unsigned int ret = 0; - if (this->classification_ != TYPE_FORWARD) - ret += this->classification_; - return ret + this->do_hash_for_method(gogo, flags); + const Type* t = this->forwarded(); + if (t->named_type() != NULL && t->named_type()->is_alias()) + { + unsigned int r = + t->named_type()->real_type()->hash_for_method(gogo, flags); + if ((flags & Type::COMPARE_ALIASES) != 0) + r += TYPE_FORWARD; + return r; + } + unsigned int ret = t->classification_; + return ret + t->do_hash_for_method(gogo, flags); } // Default implementation of do_hash_for_method. This is appropriate Index: gcc/go/gofrontend/types.h =================================================================== --- gcc/go/gofrontend/types.h (revision 265296) +++ gcc/go/gofrontend/types.h (working copy) @@ -574,6 +574,9 @@ class Type // struct field tags for purposes of type conversion. static const int COMPARE_TAGS = 2; + // Compare aliases: treat an alias to T as distinct from T. + static const int COMPARE_ALIASES = 4; + // Return true if two types are identical. If this returns false, // and REASON is not NULL, it may set *REASON. static bool