Use a different identity function for Types in hash tables.

From-SVN: r167866
This commit is contained in:
Ian Lance Taylor 2010-12-15 18:33:34 +00:00
parent 140806fa55
commit 2a3b37c3b9
2 changed files with 39 additions and 9 deletions

View File

@ -393,6 +393,38 @@ Type::are_identical(const Type* t1, const Type* t2, std::string* reason)
}
}
// Return true if two types are identical when it comes to storing
// them in a hash table. This differs from Type::are_identical with
// regard to how we handle error types. We want to treat error types
// as identical to other types when it comes to reporting
// compatibility errors, but we want to treat them as different when
// it comes to storing them in a hash table.
bool
Type::are_identical_for_hash_table(const Type* t1, const Type *t2)
{
if (t1 == NULL || t2 == NULL)
return t1 == t2;
t1 = t1->forwarded();
t2 = t2->forwarded();
if (t1 == t2)
return true;
// Undefined forward declarations are only equal to themselves.
if (t1->forward_declaration_type() != NULL
|| t2->forward_declaration_type() != NULL)
return false;
// The error type is only equal to the error type.
if (t1->is_error_type() || t2->is_error_type())
return t1->is_error_type() && t2->is_error_type();
// Otherwise we can use the usual identity check.
return Type::are_identical(t1, t2, NULL);
}
// Return true if it's OK to have a binary operation with types LHS
// and RHS. This is not used for shifts or comparisons.
@ -810,14 +842,6 @@ Type::get_tree(Gogo* gogo)
tree t = this->get_tree_without_hash(gogo);
// Don't store errors in the hash table. This type might be a
// pointer to an error type or something like that. Since error
// types are identical to everything else, that could cause us to
// return error_mark_node for pointers to any type, which will then
// confuse us later.
if (t == error_mark_node)
return error_mark_node;
if (ins.first->second == NULL_TREE)
ins.first->second = t;
else

View File

@ -508,6 +508,12 @@ class Type
static bool
are_identical(const Type* lhs, const Type* rhs, std::string* reason);
// Return true if two types are identical when it comes to putting
// them in a hash table. This differs from are_identical only in
// how error types are handled.
static bool
are_identical_for_hash_table(const Type*, const Type*);
// Return true if two types are compatible for use in a binary
// operation, other than a shift, comparison, or channel send. This
// is an equivalence relation.
@ -1104,7 +1110,7 @@ class Type_identical
public:
bool
operator()(const Type* t1, const Type* t2) const
{ return Type::are_identical(t1, t2, NULL); }
{ return Type::are_identical_for_hash_table(t1, t2); }
};
// An identifier with a type.