Use a different identity function for Types in hash tables.
From-SVN: r167866
This commit is contained in:
parent
140806fa55
commit
2a3b37c3b9
@ -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
|
// Return true if it's OK to have a binary operation with types LHS
|
||||||
// and RHS. This is not used for shifts or comparisons.
|
// 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);
|
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)
|
if (ins.first->second == NULL_TREE)
|
||||||
ins.first->second = t;
|
ins.first->second = t;
|
||||||
else
|
else
|
||||||
|
@ -508,6 +508,12 @@ class Type
|
|||||||
static bool
|
static bool
|
||||||
are_identical(const Type* lhs, const Type* rhs, std::string* reason);
|
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
|
// Return true if two types are compatible for use in a binary
|
||||||
// operation, other than a shift, comparison, or channel send. This
|
// operation, other than a shift, comparison, or channel send. This
|
||||||
// is an equivalence relation.
|
// is an equivalence relation.
|
||||||
@ -1104,7 +1110,7 @@ class Type_identical
|
|||||||
public:
|
public:
|
||||||
bool
|
bool
|
||||||
operator()(const Type* t1, const Type* t2) const
|
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.
|
// An identifier with a type.
|
||||||
|
Loading…
Reference in New Issue
Block a user