diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2017-06-14 19:01:59 +0200 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2017-06-14 19:01:59 +0200 |
commit | 6a44c6f4b668d633ea8e097fb5dfc5670bb5d9cb (patch) | |
tree | 427c7bc803972a45930fb025cc2985d65f04f3a1 /gcc/go | |
parent | bdbf0a2323816aefa5ae9753c012d44df53774c6 (diff) |
Merge branches/gcc-7-branch rev 249190.
Change-Id: I29353b553aba293581d8240e44db829cdc51b308
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 123 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 33 |
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. |