From 5900d7553a7e9bf90d6bfeca0df90ab250b2c657 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 21 Oct 2014 16:00:50 +0000 Subject: [PATCH] compiler: Remove obsolete hidden_fields_are_ok code. The language used to forbid assigning structs with hidden fields, but that was changed before the Go 1 release. At the time the change was experimental, so I left the old code in the compiler. At this point it's clearly not experimental, so this removes the unused code. From-SVN: r216519 --- gcc/go/gofrontend/expressions.cc | 18 ++--- gcc/go/gofrontend/expressions.h | 13 +-- gcc/go/gofrontend/statements.cc | 75 +++-------------- gcc/go/gofrontend/statements.h | 22 +---- gcc/go/gofrontend/types.cc | 134 +++---------------------------- gcc/go/gofrontend/types.h | 43 +--------- 6 files changed, 31 insertions(+), 274 deletions(-) diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 2f7bf2bbe16..a835ee8378f 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -9305,13 +9305,7 @@ Call_expression::check_argument_type(int i, const Type* parameter_type, bool issued_error) { std::string reason; - bool ok; - if (this->are_hidden_fields_ok_) - ok = Type::are_assignable_hidden_ok(parameter_type, argument_type, - &reason); - else - ok = Type::are_assignable(parameter_type, argument_type, &reason); - if (!ok) + if (!Type::are_assignable(parameter_type, argument_type, &reason)) { if (!issued_error) { @@ -9359,13 +9353,11 @@ Call_expression::do_check_types(Gogo*) go_assert(this->args_ != NULL && !this->args_->empty()); Type* rtype = fntype->receiver()->type(); Expression* first_arg = this->args_->front(); - // The language permits copying hidden fields for a method - // receiver. We dereference the values since receivers are - // always passed as pointers. + // We dereference the values since receivers are always passed + // as pointers. std::string reason; - if (!Type::are_assignable_hidden_ok(rtype->deref(), - first_arg->type()->deref(), - &reason)) + if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(), + &reason)) { if (reason.empty()) this->report_error(_("incompatible type for receiver")); diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 77153dbd58f..c6b163e715d 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -1617,8 +1617,8 @@ class Call_expression : public Expression : Expression(EXPRESSION_CALL, location), fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL), call_temp_(NULL), expected_result_count_(0), is_varargs_(is_varargs), - are_hidden_fields_ok_(false), varargs_are_lowered_(false), - types_are_determined_(false), is_deferred_(false), issued_error_(false) + varargs_are_lowered_(false), types_are_determined_(false), + is_deferred_(false), issued_error_(false) { } // The function to call. @@ -1674,12 +1674,6 @@ class Call_expression : public Expression set_varargs_are_lowered() { this->varargs_are_lowered_ = true; } - // Note that it is OK for this call to set hidden fields when - // passing arguments. - void - set_hidden_fields_are_ok() - { this->are_hidden_fields_ok_ = true; } - // Whether this call is being deferred. bool is_deferred() const @@ -1788,9 +1782,6 @@ class Call_expression : public Expression size_t expected_result_count_; // True if the last argument is a varargs argument (f(a...)). bool is_varargs_; - // True if this statement may pass hidden fields in the arguments. - // This is used for generated method stubs. - bool are_hidden_fields_ok_; // True if varargs have already been lowered. bool varargs_are_lowered_; // True if types have been determined. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 0478e208588..183aaf4f8ab 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -409,13 +409,7 @@ Temporary_statement::do_check_types(Gogo*) if (this->type_ != NULL && this->init_ != NULL) { std::string reason; - bool ok; - if (this->are_hidden_fields_ok_) - ok = Type::are_assignable_hidden_ok(this->type_, this->init_->type(), - &reason); - else - ok = Type::are_assignable(this->type_, this->init_->type(), &reason); - if (!ok) + if (!Type::are_assignable(this->type_, this->init_->type(), &reason)) { if (reason.empty()) error_at(this->location(), "incompatible types in assignment"); @@ -511,15 +505,9 @@ class Assignment_statement : public Statement Assignment_statement(Expression* lhs, Expression* rhs, Location location) : Statement(STATEMENT_ASSIGNMENT, location), - lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false) + lhs_(lhs), rhs_(rhs) { } - // Note that it is OK for this assignment statement to set hidden - // fields. - void - set_hidden_fields_are_ok() - { this->are_hidden_fields_ok_ = true; } - protected: int do_traverse(Traverse* traverse); @@ -544,9 +532,6 @@ class Assignment_statement : public Statement Expression* lhs_; // Right hand side--the rvalue. Expression* rhs_; - // True if this statement may set hidden fields in the assignment - // statement. This is used for generated method stubs. - bool are_hidden_fields_ok_; }; // Traversal. @@ -607,12 +592,7 @@ Assignment_statement::do_check_types(Gogo*) } std::string reason; - bool ok; - if (this->are_hidden_fields_ok_) - ok = Type::are_assignable_hidden_ok(lhs_type, rhs_type, &reason); - else - ok = Type::are_assignable(lhs_type, rhs_type, &reason); - if (!ok) + if (!Type::are_assignable(lhs_type, rhs_type, &reason)) { if (reason.empty()) error_at(this->location(), "incompatible types in assignment"); @@ -905,15 +885,9 @@ class Tuple_assignment_statement : public Statement Tuple_assignment_statement(Expression_list* lhs, Expression_list* rhs, Location location) : Statement(STATEMENT_TUPLE_ASSIGNMENT, location), - lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false) + lhs_(lhs), rhs_(rhs) { } - // Note that it is OK for this assignment statement to set hidden - // fields. - void - set_hidden_fields_are_ok() - { this->are_hidden_fields_ok_ = true; } - protected: int do_traverse(Traverse* traverse); @@ -937,9 +911,6 @@ class Tuple_assignment_statement : public Statement Expression_list* lhs_; // Right hand side--a list of rvalues. Expression_list* rhs_; - // True if this statement may set hidden fields in the assignment - // statement. This is used for generated method stubs. - bool are_hidden_fields_ok_; }; // Traversal. @@ -998,8 +969,6 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, Temporary_statement* temp = Statement::make_temporary((*plhs)->type(), *prhs, loc); - if (this->are_hidden_fields_ok_) - temp->set_hidden_fields_are_ok(); b->add_statement(temp); temps.push_back(temp); @@ -1022,13 +991,7 @@ Tuple_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing, continue; Expression* ref = Expression::make_temporary_reference(*ptemp, loc); - Statement* s = Statement::make_assignment(*plhs, ref, loc); - if (this->are_hidden_fields_ok_) - { - Assignment_statement* as = static_cast(s); - as->set_hidden_fields_are_ok(); - } - b->add_statement(s); + b->add_statement(Statement::make_assignment(*plhs, ref, loc)); ++ptemp; } go_assert(ptemp == temps.end() || saw_errors()); @@ -2736,12 +2699,7 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing, e->determine_type(&type_context); std::string reason; - bool ok; - if (this->are_hidden_fields_ok_) - ok = Type::are_assignable_hidden_ok(rvtype, e->type(), &reason); - else - ok = Type::are_assignable(rvtype, e->type(), &reason); - if (ok) + if (Type::are_assignable(rvtype, e->type(), &reason)) { Expression* ve = Expression::make_var_reference(rv, e->location()); lhs->push_back(ve); @@ -2763,28 +2721,13 @@ Return_statement::do_lower(Gogo*, Named_object* function, Block* enclosing, ; else if (lhs->size() == 1) { - Statement* s = Statement::make_assignment(lhs->front(), rhs->front(), - loc); - if (this->are_hidden_fields_ok_) - { - Assignment_statement* as = static_cast(s); - as->set_hidden_fields_are_ok(); - } - b->add_statement(s); + b->add_statement(Statement::make_assignment(lhs->front(), rhs->front(), + loc)); delete lhs; delete rhs; } else - { - Statement* s = Statement::make_tuple_assignment(lhs, rhs, loc); - if (this->are_hidden_fields_ok_) - { - Tuple_assignment_statement* tas = - static_cast(s); - tas->set_hidden_fields_are_ok(); - } - b->add_statement(s); - } + b->add_statement(Statement::make_tuple_assignment(lhs, rhs, loc)); b->add_statement(this); diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h index 7d9bcfde8b7..9bb0fb5aa8d 100644 --- a/gcc/go/gofrontend/statements.h +++ b/gcc/go/gofrontend/statements.h @@ -514,8 +514,7 @@ class Temporary_statement : public Statement public: Temporary_statement(Type* type, Expression* init, Location location) : Statement(STATEMENT_TEMPORARY, location), - type_(type), init_(init), bvariable_(NULL), are_hidden_fields_ok_(false), - is_address_taken_(false) + type_(type), init_(init), bvariable_(NULL), is_address_taken_(false) { } // Return the type of the temporary variable. @@ -527,11 +526,6 @@ class Temporary_statement : public Statement init() const { return this->init_; } - // Note that it is OK for this statement to set hidden fields. - void - set_hidden_fields_are_ok() - { this->are_hidden_fields_ok_ = true; } - // Record that something takes the address of this temporary // variable. void @@ -569,9 +563,6 @@ class Temporary_statement : public Statement Expression* init_; // The backend representation of the temporary variable. Bvariable* bvariable_; - // True if this statement may set hidden fields when assigning the - // value to the temporary. This is used for generated method stubs. - bool are_hidden_fields_ok_; // True if something takes the address of this temporary variable. bool is_address_taken_; }; @@ -619,7 +610,7 @@ class Return_statement : public Statement public: Return_statement(Expression_list* vals, Location location) : Statement(STATEMENT_RETURN, location), - vals_(vals), are_hidden_fields_ok_(false), is_lowered_(false) + vals_(vals), is_lowered_(false) { } // The list of values being returned. This may be NULL. @@ -627,12 +618,6 @@ class Return_statement : public Statement vals() const { return this->vals_; } - // Note that it is OK for this return statement to set hidden - // fields. - void - set_hidden_fields_are_ok() - { this->are_hidden_fields_ok_ = true; } - protected: int do_traverse(Traverse* traverse) @@ -657,9 +642,6 @@ class Return_statement : public Statement private: // Return values. This may be NULL. Expression_list* vals_; - // True if this statement may pass hidden fields in the return - // value. This is used for generated method stubs. - bool are_hidden_fields_ok_; // True if this statement has been lowered. bool is_lowered_; }; diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index fb7ebee9423..0d66abf5081 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -594,14 +594,11 @@ Type::are_compatible_for_comparison(bool is_equality_op, const Type *t1, } // Return true if a value with type RHS may be assigned to a variable -// with type LHS. If CHECK_HIDDEN_FIELDS is true, check whether any -// hidden fields are modified. If REASON is not NULL, set *REASON to -// the reason the types are not assignable. +// with type LHS. If REASON is not NULL, set *REASON to the reason +// the types are not assignable. bool -Type::are_assignable_check_hidden(const Type* lhs, const Type* rhs, - bool check_hidden_fields, - std::string* reason) +Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason) { // Do some checks first. Make sure the types are defined. if (rhs != NULL && !rhs->is_undefined()) @@ -621,21 +618,11 @@ Type::are_assignable_check_hidden(const Type* lhs, const Type* rhs, } } - if (lhs != NULL && !lhs->is_undefined()) - { - // Any value may be assigned to the blank identifier. - if (lhs->is_sink_type()) - return true; - - // All fields of a struct must be exported, or the assignment - // must be in the same package. - if (check_hidden_fields && rhs != NULL && !rhs->is_undefined()) - { - if (lhs->has_hidden_fields(NULL, reason) - || rhs->has_hidden_fields(NULL, reason)) - return false; - } - } + // Any value may be assigned to the blank identifier. + if (lhs != NULL + && !lhs->is_undefined() + && lhs->is_sink_type()) + return true; // Identical types are assignable. if (Type::are_identical(lhs, rhs, true, reason)) @@ -720,25 +707,6 @@ Type::are_assignable_check_hidden(const Type* lhs, const Type* rhs, return false; } -// Return true if a value with type RHS may be assigned to a variable -// with type LHS. If REASON is not NULL, set *REASON to the reason -// the types are not assignable. - -bool -Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason) -{ - return Type::are_assignable_check_hidden(lhs, rhs, false, reason); -} - -// Like are_assignable but don't check for hidden fields. - -bool -Type::are_assignable_hidden_ok(const Type* lhs, const Type* rhs, - std::string* reason) -{ - return Type::are_assignable_check_hidden(lhs, rhs, false, reason); -} - // Return true if a value with type RHS may be converted to type LHS. // If REASON is not NULL, set *REASON to the reason the types are not // convertible. @@ -833,25 +801,6 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) return false; } -// Return whether this type has any hidden fields. This is only a -// possibility for a few types. - -bool -Type::has_hidden_fields(const Named_type* within, std::string* reason) const -{ - switch (this->forwarded()->classification_) - { - case TYPE_NAMED: - return this->named_type()->named_type_has_hidden_fields(reason); - case TYPE_STRUCT: - return this->struct_type()->struct_has_hidden_fields(within, reason); - case TYPE_ARRAY: - return this->array_type()->array_has_hidden_fields(within, reason); - default: - return false; - } -} - // Return a hash code for the type to be used for method lookup. unsigned int @@ -4828,49 +4777,6 @@ Struct_type::is_identical(const Struct_type* t, return true; } -// Whether this struct type has any hidden fields. - -bool -Struct_type::struct_has_hidden_fields(const Named_type* within, - std::string* reason) const -{ - const Struct_field_list* fields = this->fields(); - if (fields == NULL) - return false; - const Package* within_package = (within == NULL - ? NULL - : within->named_object()->package()); - for (Struct_field_list::const_iterator pf = fields->begin(); - pf != fields->end(); - ++pf) - { - if (within_package != NULL - && !pf->is_anonymous() - && Gogo::is_hidden_name(pf->field_name())) - { - if (reason != NULL) - { - std::string within_name = within->named_object()->message_name(); - std::string name = Gogo::message_name(pf->field_name()); - size_t bufsize = 200 + within_name.length() + name.length(); - char* buf = new char[bufsize]; - snprintf(buf, bufsize, - _("implicit assignment of %s%s%s hidden field %s%s%s"), - open_quote, within_name.c_str(), close_quote, - open_quote, name.c_str(), close_quote); - reason->assign(buf); - delete[] buf; - } - return true; - } - - if (pf->type()->has_hidden_fields(within, reason)) - return true; - } - - return false; -} - // Whether comparisons of this struct type are simple identity // comparisons. @@ -8633,19 +8539,6 @@ Named_type::interface_method_table(Interface_type* interface, bool is_pointer) &this->pointer_interface_method_tables_); } -// Return whether a named type has any hidden fields. - -bool -Named_type::named_type_has_hidden_fields(std::string* reason) const -{ - if (this->seen_) - return false; - this->seen_ = true; - bool ret = this->type_->has_hidden_fields(this, reason); - this->seen_ = false; - return ret; -} - // Look for a use of a complete type within another type. This is // used to check that we don't try to use a type within itself. @@ -9772,17 +9665,8 @@ Type::build_one_stub_method(Gogo* gogo, Method* method, go_assert(func != NULL); Call_expression* call = Expression::make_call(func, arguments, is_varargs, location); - call->set_hidden_fields_are_ok(); - Statement* s = Statement::make_return_from_call(call, location); - Return_statement* retstat = s->return_statement(); - if (retstat != NULL) - { - // We can return values with hidden fields from a stub. This is - // necessary if the method is itself hidden. - retstat->set_hidden_fields_are_ok(); - } - gogo->add_statement(s); + gogo->add_statement(Statement::make_return_from_call(call, location)); } // Apply FIELD_INDEXES to EXPR. The field indexes have to be applied diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index 2173bab8353..60de22e1fe1 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -611,27 +611,12 @@ class Type static bool are_assignable(const Type* lhs, const Type* rhs, std::string* reason); - // Return true if a value with type RHS is assignable to a variable - // with type LHS, ignoring any assignment of hidden fields - // (unexported fields of a type imported from another package). - // This is like the are_assignable method. - static bool - are_assignable_hidden_ok(const Type* lhs, const Type* rhs, - std::string* reason); - // Return true if a value with type RHS may be converted to type // LHS. If this returns false, and REASON is not NULL, it sets // *REASON. static bool are_convertible(const Type* lhs, const Type* rhs, std::string* reason); - // Whether this type has any hidden fields which are not visible in - // the current compilation, such as a field whose name begins with a - // lower case letter in a struct imported from a different package. - // WITHIN is not NULL if we are looking at fields in a named type. - bool - has_hidden_fields(const Named_type* within, std::string* reason) const; - // Return true if values of this type can be compared using an // identity function which gets nothing but a pointer to the value // and a size. @@ -1160,11 +1145,6 @@ class Type : NULL); } - // Support for are_assignable and are_assignable_hidden_ok. - static bool - are_assignable_check_hidden(const Type* lhs, const Type* rhs, - bool check_hidden_fields, std::string* reason); - // Map unnamed types to type descriptor decls. typedef Unordered_map_hash(const Type*, Bvariable*, Type_hash_identical, Type_identical) Type_descriptor_vars; @@ -2236,12 +2216,6 @@ class Struct_type : public Type bool is_identical(const Struct_type* t, bool errors_are_identical) const; - // Whether this struct type has any hidden fields. This returns - // true if any fields have hidden names, or if any non-pointer - // anonymous fields have types with hidden fields. - bool - struct_has_hidden_fields(const Named_type* within, std::string*) const; - // Return whether NAME is a local field which is not exported. This // is only used for better error reporting. bool @@ -2403,11 +2377,6 @@ class Array_type : public Type bool is_identical(const Array_type* t, bool errors_are_identical) const; - // Whether this type has any hidden fields. - bool - array_has_hidden_fields(const Named_type* within, std::string* reason) const - { return this->element_type_->has_hidden_fields(within, reason); } - // Return an expression for the pointer to the values in an array. Expression* get_value_pointer(Gogo*, Expression* array) const; @@ -3037,10 +3006,6 @@ class Named_type : public Type Expression* interface_method_table(Interface_type* interface, bool is_pointer); - // Whether this type has any hidden fields. - bool - named_type_has_hidden_fields(std::string* reason) const; - // Note that a type must be converted to the backend representation // before we convert this type. void @@ -3160,10 +3125,10 @@ class Named_type : public Type bool is_circular_; // Whether this type has been verified. bool is_verified_; - // In a recursive operation such as has_hidden_fields, this flag is - // used to prevent infinite recursion when a type refers to itself. - // This is mutable because it is always reset to false when the - // function exits. + // In a recursive operation such as has_pointer, this flag is used + // to prevent infinite recursion when a type refers to itself. This + // is mutable because it is always reset to false when the function + // exits. mutable bool seen_; // Like seen_, but used only by do_compare_is_identity. bool seen_in_compare_is_identity_; -- 2.30.2