aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2017-06-14 19:01:59 +0200
committerYvan Roux <yvan.roux@linaro.org>2017-06-14 19:01:59 +0200
commit6a44c6f4b668d633ea8e097fb5dfc5670bb5d9cb (patch)
tree427c7bc803972a45930fb025cc2985d65f04f3a1 /gcc/go
parentbdbf0a2323816aefa5ae9753c012d44df53774c6 (diff)
Merge branches/gcc-7-branch rev 249190.
Change-Id: I29353b553aba293581d8240e44db829cdc51b308
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/ChangeLog6
-rw-r--r--gcc/go/go-gcc.cc4
-rw-r--r--gcc/go/gofrontend/types.cc123
-rw-r--r--gcc/go/gofrontend/types.h33
4 files changed, 108 insertions, 58 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index e27cef9a5b6..a586845b446 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,9 @@
+2017-05-11 Ian Lance Taylor <iant@google.com>
+
+ PR go/64238
+ * go-gcc.cc (Gcc_backend::implicit_variable_reference): Set
+ DECL_EXTERNAL, clear TREE_STATIC.
+
2017-05-02 Release Manager
* GCC 7.1.0 released.
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 62baa91fab8..3a982d0547c 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -2811,9 +2811,9 @@ Gcc_backend::implicit_variable_reference(const std::string& name,
tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
get_identifier_from_string(name), type_tree);
- DECL_EXTERNAL(decl) = 0;
+ DECL_EXTERNAL(decl) = 1;
TREE_PUBLIC(decl) = 1;
- TREE_STATIC(decl) = 1;
+ TREE_STATIC(decl) = 0;
DECL_ARTIFICIAL(decl) = 1;
if (! asm_name.empty())
SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(asm_name));
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index f65dbd73c33..e1e0f7a7b19 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -317,6 +317,16 @@ bool
Type::are_identical(const Type* t1, const Type* t2, bool errors_are_identical,
std::string* reason)
{
+ return Type::are_identical_cmp_tags(t1, t2, COMPARE_TAGS,
+ errors_are_identical, reason);
+}
+
+// Like are_identical, but with a CMP_TAGS parameter.
+
+bool
+Type::are_identical_cmp_tags(const Type* t1, const Type* t2, Cmp_tags cmp_tags,
+ bool errors_are_identical, std::string* reason)
+{
if (t1 == NULL || t2 == NULL)
{
// Something is wrong.
@@ -387,31 +397,33 @@ Type::are_identical(const Type* t1, const Type* t2, bool errors_are_identical,
case TYPE_FUNCTION:
return t1->function_type()->is_identical(t2->function_type(),
false,
+ cmp_tags,
errors_are_identical,
reason);
case TYPE_POINTER:
- return Type::are_identical(t1->points_to(), t2->points_to(),
- errors_are_identical, reason);
+ return Type::are_identical_cmp_tags(t1->points_to(), t2->points_to(),
+ cmp_tags, errors_are_identical,
+ reason);
case TYPE_STRUCT:
- return t1->struct_type()->is_identical(t2->struct_type(),
+ return t1->struct_type()->is_identical(t2->struct_type(), cmp_tags,
errors_are_identical);
case TYPE_ARRAY:
- return t1->array_type()->is_identical(t2->array_type(),
+ return t1->array_type()->is_identical(t2->array_type(), cmp_tags,
errors_are_identical);
case TYPE_MAP:
- return t1->map_type()->is_identical(t2->map_type(),
+ return t1->map_type()->is_identical(t2->map_type(), cmp_tags,
errors_are_identical);
case TYPE_CHANNEL:
- return t1->channel_type()->is_identical(t2->channel_type(),
+ return t1->channel_type()->is_identical(t2->channel_type(), cmp_tags,
errors_are_identical);
case TYPE_INTERFACE:
- return t1->interface_type()->is_identical(t2->interface_type(),
+ return t1->interface_type()->is_identical(t2->interface_type(), cmp_tags,
errors_are_identical);
case TYPE_CALL_MULTIPLE_RESULT:
@@ -735,23 +747,26 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
return true;
// The types are convertible if they have identical underlying
- // types.
+ // types, ignoring struct field tags.
if ((lhs->named_type() != NULL || rhs->named_type() != NULL)
- && Type::are_identical(lhs->base(), rhs->base(), true, reason))
+ && Type::are_identical_cmp_tags(lhs->base(), rhs->base(), IGNORE_TAGS,
+ true, reason))
return true;
// The types are convertible if they are both unnamed pointer types
- // and their pointer base types have identical underlying types.
+ // and their pointer base types have identical underlying types,
+ // ignoring struct field tags.
if (lhs->named_type() == NULL
&& rhs->named_type() == NULL
&& lhs->points_to() != NULL
&& rhs->points_to() != NULL
&& (lhs->points_to()->named_type() != NULL
|| rhs->points_to()->named_type() != NULL)
- && Type::are_identical(lhs->points_to()->base(),
- rhs->points_to()->base(),
- true,
- reason))
+ && Type::are_identical_cmp_tags(lhs->points_to()->base(),
+ rhs->points_to()->base(),
+ IGNORE_TAGS,
+ true,
+ reason))
return true;
// Integer and floating point types are convertible to each other.
@@ -3758,7 +3773,7 @@ bool
Function_type::is_valid_redeclaration(const Function_type* t,
std::string* reason) const
{
- if (!this->is_identical(t, false, true, reason))
+ if (!this->is_identical(t, false, COMPARE_TAGS, true, reason))
return false;
// A redeclaration of a function is required to use the same names
@@ -3836,7 +3851,7 @@ Function_type::is_valid_redeclaration(const Function_type* t,
bool
Function_type::is_identical(const Function_type* t, bool ignore_receiver,
- bool errors_are_identical,
+ Cmp_tags cmp_tags, bool errors_are_identical,
std::string* reason) const
{
if (!ignore_receiver)
@@ -3851,8 +3866,8 @@ Function_type::is_identical(const Function_type* t, bool ignore_receiver,
}
if (r1 != NULL)
{
- if (!Type::are_identical(r1->type(), r2->type(), errors_are_identical,
- reason))
+ if (!Type::are_identical_cmp_tags(r1->type(), r2->type(), cmp_tags,
+ errors_are_identical, reason))
{
if (reason != NULL && !reason->empty())
*reason = "receiver: " + *reason;
@@ -3883,8 +3898,8 @@ Function_type::is_identical(const Function_type* t, bool ignore_receiver,
return false;
}
- if (!Type::are_identical(p1->type(), p2->type(),
- errors_are_identical, NULL))
+ if (!Type::are_identical_cmp_tags(p1->type(), p2->type(), cmp_tags,
+ errors_are_identical, NULL))
{
if (reason != NULL)
*reason = _("different parameter types");
@@ -3928,8 +3943,9 @@ Function_type::is_identical(const Function_type* t, bool ignore_receiver,
return false;
}
- if (!Type::are_identical(res1->type(), res2->type(),
- errors_are_identical, NULL))
+ if (!Type::are_identical_cmp_tags(res1->type(), res2->type(),
+ cmp_tags, errors_are_identical,
+ NULL))
{
if (reason != NULL)
*reason = _("different result types");
@@ -5103,7 +5119,7 @@ Struct_type::do_has_pointer() const
// Whether this type is identical to T.
bool
-Struct_type::is_identical(const Struct_type* t,
+Struct_type::is_identical(const Struct_type* t, Cmp_tags cmp_tags,
bool errors_are_identical) const
{
if (this->is_struct_incomparable_ != t->is_struct_incomparable_)
@@ -5122,20 +5138,23 @@ Struct_type::is_identical(const Struct_type* t,
if (pf1->field_name() != pf2->field_name())
return false;
if (pf1->is_anonymous() != pf2->is_anonymous()
- || !Type::are_identical(pf1->type(), pf2->type(),
- errors_are_identical, NULL))
+ || !Type::are_identical_cmp_tags(pf1->type(), pf2->type(), cmp_tags,
+ errors_are_identical, NULL))
return false;
- if (!pf1->has_tag())
+ if (cmp_tags == COMPARE_TAGS)
{
- if (pf2->has_tag())
- return false;
- }
- else
- {
- if (!pf2->has_tag())
- return false;
- if (pf1->tag() != pf2->tag())
- return false;
+ if (!pf1->has_tag())
+ {
+ if (pf2->has_tag())
+ return false;
+ }
+ else
+ {
+ if (!pf2->has_tag())
+ return false;
+ if (pf1->tag() != pf2->tag())
+ return false;
+ }
}
}
if (pf2 != fields2->end())
@@ -6363,10 +6382,11 @@ Type::make_struct_type(Struct_field_list* fields,
// Whether two array types are identical.
bool
-Array_type::is_identical(const Array_type* t, bool errors_are_identical) const
+Array_type::is_identical(const Array_type* t, Cmp_tags cmp_tags,
+ bool errors_are_identical) const
{
- if (!Type::are_identical(this->element_type(), t->element_type(),
- errors_are_identical, NULL))
+ if (!Type::are_identical_cmp_tags(this->element_type(), t->element_type(),
+ cmp_tags, errors_are_identical, NULL))
return false;
if (this->is_array_incomparable_ != t->is_array_incomparable_)
@@ -7370,12 +7390,14 @@ Map_type::do_verify()
// Whether two map types are identical.
bool
-Map_type::is_identical(const Map_type* t, bool errors_are_identical) const
+Map_type::is_identical(const Map_type* t, Cmp_tags cmp_tags,
+ bool errors_are_identical) const
{
- return (Type::are_identical(this->key_type(), t->key_type(),
- errors_are_identical, NULL)
- && Type::are_identical(this->val_type(), t->val_type(),
- errors_are_identical, NULL));
+ return (Type::are_identical_cmp_tags(this->key_type(), t->key_type(),
+ cmp_tags, errors_are_identical, NULL)
+ && Type::are_identical_cmp_tags(this->val_type(), t->val_type(),
+ cmp_tags, errors_are_identical,
+ NULL));
}
// Hash code.
@@ -7909,11 +7931,11 @@ Channel_type::do_hash_for_method(Gogo* gogo) const
// Whether this type is the same as T.
bool
-Channel_type::is_identical(const Channel_type* t,
+Channel_type::is_identical(const Channel_type* t, Cmp_tags cmp_tags,
bool errors_are_identical) const
{
- if (!Type::are_identical(this->element_type(), t->element_type(),
- errors_are_identical, NULL))
+ if (!Type::are_identical_cmp_tags(this->element_type(), t->element_type(),
+ cmp_tags, errors_are_identical, NULL))
return false;
return (this->may_send_ == t->may_send_
&& this->may_receive_ == t->may_receive_);
@@ -8341,7 +8363,7 @@ Interface_type::is_unexported_method(Gogo* gogo, const std::string& name) const
// Whether this type is identical with T.
bool
-Interface_type::is_identical(const Interface_type* t,
+Interface_type::is_identical(const Interface_type* t, Cmp_tags cmp_tags,
bool errors_are_identical) const
{
// If methods have not been finalized, then we are asking whether
@@ -8372,8 +8394,8 @@ Interface_type::is_identical(const Interface_type* t,
if (p1 == this->all_methods_->end())
break;
if (p1->name() != p2->name()
- || !Type::are_identical(p1->type(), p2->type(),
- errors_are_identical, NULL))
+ || !Type::are_identical_cmp_tags(p1->type(), p2->type(), cmp_tags,
+ errors_are_identical, NULL))
break;
}
@@ -8571,7 +8593,8 @@ Interface_type::implements_interface(const Type* t, std::string* reason) const
Function_type* m_fn_type = m->type()->function_type();
go_assert(p_fn_type != NULL && m_fn_type != NULL);
std::string subreason;
- if (!p_fn_type->is_identical(m_fn_type, true, true, &subreason))
+ if (!p_fn_type->is_identical(m_fn_type, true, COMPARE_TAGS, true,
+ &subreason))
{
if (reason != NULL)
{
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 47a70fcd08f..954bccf036f 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -590,6 +590,22 @@ class Type
are_identical(const Type* lhs, const Type* rhs, bool errors_are_identical,
std::string* reason);
+ // An argument to are_identical_cmp_tags, indicating whether or not
+ // to compare struct field tags.
+ enum Cmp_tags {
+ COMPARE_TAGS,
+ IGNORE_TAGS
+ };
+
+ // Return true if two types are identical. This is like the
+ // are_identical function, but also takes a CMP_TAGS argument
+ // indicating whether to compare struct tags. Otherwise the
+ // parameters are as for are_identical.
+ static bool
+ are_identical_cmp_tags(const Type* lhs, const Type* rhs,
+ Cmp_tags, bool errors_are_identical,
+ std::string* reason);
+
// 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.
@@ -1922,7 +1938,7 @@ class Function_type : public Type
// Whether this type is the same as T.
bool
is_identical(const Function_type* t, bool ignore_receiver,
- bool errors_are_identical, std::string*) const;
+ Cmp_tags, bool errors_are_identical, std::string*) const;
// Record that this is a varargs function.
void
@@ -2322,7 +2338,8 @@ class Struct_type : public Type
// Whether this type is identical with T.
bool
- is_identical(const Struct_type* t, bool errors_are_identical) const;
+ is_identical(const Struct_type* t, Cmp_tags,
+ bool errors_are_identical) const;
// Return whether NAME is a local field which is not exported. This
// is only used for better error reporting.
@@ -2521,7 +2538,8 @@ class Array_type : public Type
// Whether this type is identical with T.
bool
- is_identical(const Array_type* t, bool errors_are_identical) const;
+ is_identical(const Array_type* t, Cmp_tags,
+ bool errors_are_identical) const;
// Return an expression for the pointer to the values in an array.
Expression*
@@ -2694,7 +2712,8 @@ class Map_type : public Type
// Whether this type is identical with T.
bool
- is_identical(const Map_type* t, bool errors_are_identical) const;
+ is_identical(const Map_type* t, Cmp_tags,
+ bool errors_are_identical) const;
// Import a map type.
static Map_type*
@@ -2814,7 +2833,8 @@ class Channel_type : public Type
// Whether this type is identical with T.
bool
- is_identical(const Channel_type* t, bool errors_are_identical) const;
+ is_identical(const Channel_type* t, Cmp_tags,
+ bool errors_are_identical) const;
// Import a channel type.
static Channel_type*
@@ -2927,7 +2947,8 @@ class Interface_type : public Type
// Whether this type is identical with T. REASON is as in
// implements_interface.
bool
- is_identical(const Interface_type* t, bool errors_are_identical) const;
+ is_identical(const Interface_type* t, Cmp_tags,
+ bool errors_are_identical) const;
// Whether we can assign T to this type. is_identical is known to
// be false.