aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-11-16 14:47:28 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-11-16 14:47:28 +0000
commit307ca54339bfce88e67f7e446ee4bbf5f1961eba (patch)
treeb1c978d18b740b9a10085a389e495460535445aa /gcc
parent711188895e4d910aef399ac37084627e003433a8 (diff)
downloadgcc-307ca54339bfce88e67f7e446ee4bbf5f1961eba.zip
gcc-307ca54339bfce88e67f7e446ee4bbf5f1961eba.tar.gz
gcc-307ca54339bfce88e67f7e446ee4bbf5f1961eba.tar.bz2
compiler: separate incomparable types from comparable ones
Otherwise we can accidentally and incorrectly mark an actual user type as incomparable. This fixes the gccgo version of https://golang.org/issue/17752. The test case for gccgo is https://golang.org/cl/33249. Reviewed-on: https://go-review.googlesource.com/33292 From-SVN: r242494
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/types.cc22
2 files changed, 21 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1fe9dec..56ba8a5 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-eb716b515356166d3177e6244619be5901f31162
+31ff8c31d33c3e77cae4fd55445f12825eb92af5
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 1635709..bc6e3c6 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -4792,6 +4792,8 @@ bool
Struct_type::is_identical(const Struct_type* t,
bool errors_are_identical) const
{
+ if (this->is_struct_incomparable_ != t->is_struct_incomparable_)
+ return false;
const Struct_field_list* fields1 = this->fields();
const Struct_field_list* fields2 = t->fields();
if (fields1 == NULL || fields2 == NULL)
@@ -4929,7 +4931,10 @@ Struct_type::do_hash_for_method(Gogo* gogo) const
++pf)
ret = (ret << 1) + pf->type()->hash_for_method(gogo);
}
- return ret <<= 2;
+ ret <<= 2;
+ if (this->is_struct_incomparable_)
+ ret <<= 1;
+ return ret;
}
// Find the local field NAME.
@@ -5659,6 +5664,9 @@ Struct_type::do_mangled_name(Gogo* gogo, std::string* ret) const
}
}
+ if (this->is_struct_incomparable_)
+ ret->push_back('x');
+
ret->push_back('e');
}
@@ -6052,6 +6060,9 @@ Array_type::is_identical(const Array_type* t, bool errors_are_identical) const
errors_are_identical, NULL))
return false;
+ if (this->is_array_incomparable_ != t->is_array_incomparable_)
+ return false;
+
Expression* l1 = this->length();
Expression* l2 = t->length();
@@ -6216,9 +6227,14 @@ Array_type::do_compare_is_identity(Gogo* gogo)
unsigned int
Array_type::do_hash_for_method(Gogo* gogo) const
{
+ unsigned int ret;
+
// There is no very convenient way to get a hash code for the
// length.
- return this->element_type_->hash_for_method(gogo) + 1;
+ ret = this->element_type_->hash_for_method(gogo) + 1;
+ if (this->is_array_incomparable_)
+ ret <<= 1;
+ return ret;
}
// Write the hash function for an array which can not use the identify
@@ -6916,6 +6932,8 @@ Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const
ret->append(s);
free(s);
mpz_clear(val);
+ if (this->is_array_incomparable_)
+ ret->push_back('x');
}
ret->push_back('e');
}