aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-02-20 13:52:56 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-02-20 13:52:56 +0000
commit731c3fc22d8edb4e9ee6655543017ce76c05bfcc (patch)
tree8ec78c4ea569b42935b65702e9f9931056a22a4a
parent6285e915c4f1b73ccbd166cdf4622da8c01a549b (diff)
downloadgcc-731c3fc22d8edb4e9ee6655543017ce76c05bfcc.zip
gcc-731c3fc22d8edb4e9ee6655543017ce76c05bfcc.tar.gz
gcc-731c3fc22d8edb4e9ee6655543017ce76c05bfcc.tar.bz2
compiler: look through aliases for type compatibility
Aliases are supposed to be identical to the type being aliased, so questions about type compatibility need to always ignore aliases, except for error messages involving the type name. The test case for this is https://golang.org/cl/94995. Fixes golang/go#23912 Reviewed-on: https://go-review.googlesource.com/94996 From-SVN: r257845
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/types.cc29
2 files changed, 21 insertions, 10 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index cb7dffd..61bed68 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-cef3934fbc63f5e121abb8f88d3799961ac95b59
+459a8a94e04a19bde7173ef7cf2db369c2e62e2d
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 40eccfc..11924e6 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -597,10 +597,10 @@ Type::are_compatible_for_comparison(bool is_equality_op, const Type *t1,
return false;
}
- if (t1->named_type() != NULL)
- return t1->named_type()->named_type_is_comparable(reason);
- else if (t2->named_type() != NULL)
- return t2->named_type()->named_type_is_comparable(reason);
+ if (t1->unalias()->named_type() != NULL)
+ return t1->unalias()->named_type()->named_type_is_comparable(reason);
+ else if (t2->unalias()->named_type() != NULL)
+ return t2->unalias()->named_type()->named_type_is_comparable(reason);
else if (t1->struct_type() != NULL)
{
if (t1->struct_type()->is_struct_incomparable())
@@ -678,6 +678,12 @@ Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason)
if (Type::are_identical(lhs, rhs, true, reason))
return true;
+ // Ignore aliases, except for error messages.
+ const Type* lhs_orig = lhs;
+ const Type* rhs_orig = rhs;
+ lhs = lhs->unalias();
+ rhs = rhs->unalias();
+
// The types are assignable if they have identical underlying types
// and either LHS or RHS is not a named type.
if (((lhs->named_type() != NULL && rhs->named_type() == NULL)
@@ -740,15 +746,16 @@ Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason)
{
if (rhs->interface_type() != NULL)
reason->assign(_("need explicit conversion"));
- else if (lhs->named_type() != NULL && rhs->named_type() != NULL)
+ else if (lhs_orig->named_type() != NULL
+ && rhs_orig->named_type() != NULL)
{
- size_t len = (lhs->named_type()->name().length()
- + rhs->named_type()->name().length()
+ size_t len = (lhs_orig->named_type()->name().length()
+ + rhs_orig->named_type()->name().length()
+ 100);
char* buf = new char[len];
snprintf(buf, len, _("cannot use type %s as type %s"),
- rhs->named_type()->message_name().c_str(),
- lhs->named_type()->message_name().c_str());
+ rhs_orig->named_type()->message_name().c_str(),
+ lhs_orig->named_type()->message_name().c_str());
reason->assign(buf);
delete[] buf;
}
@@ -768,6 +775,10 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
if (Type::are_assignable(lhs, rhs, reason))
return true;
+ // Ignore aliases.
+ lhs = lhs->unalias();
+ rhs = rhs->unalias();
+
// A pointer to a regular type may not be converted to a pointer to
// a type that may not live in the heap, except when converting from
// unsafe.Pointer.