aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/go/gofrontend/types.cc40
-rw-r--r--gcc/go/gofrontend/types.h8
2 files changed, 39 insertions, 9 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 5a75a0b..1579f17 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -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
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 3f1b8ba..43a2708 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -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.