Commit e0d475db by Ian Lance Taylor

compiler: Don't built hash/equality functions for thunk structs.

They are never necessary, and they can cause problems when a
thunk is used to pass an unexported type from a different
package to a function defined in that package.  The resulting
struct type may need to call the comparison routine from the
other package, which will fail because the type is not
exported.  This will be bug492 in the master testsuite.

From-SVN: r218798
parent c0f15a3f
......@@ -1884,6 +1884,8 @@ Statement::make_dec_statement(Expression* expr)
// Class Thunk_statement. This is the base class for go and defer
// statements.
Unordered_set(const Struct_type*) Thunk_statement::thunk_types;
// Constructor.
Thunk_statement::Thunk_statement(Statement_classification classification,
......@@ -2265,7 +2267,20 @@ Thunk_statement::build_struct(Function_type* fntype)
}
}
return Type::make_struct_type(fields, location);
Struct_type *st = Type::make_struct_type(fields, location);
Thunk_statement::thunk_types.insert(st);
return st;
}
// Return whether ST is a type created to hold thunk parameters.
bool
Thunk_statement::is_thunk_struct(const Struct_type* st)
{
return (Thunk_statement::thunk_types.find(st)
!= Thunk_statement::thunk_types.end());
}
// Build the thunk we are going to call. This is a brand new, albeit
......
......@@ -985,6 +985,10 @@ class Thunk_statement : public Statement
bool
simplify_statement(Gogo*, Named_object*, Block*);
// Return whether ST is a type created to hold thunk parameters.
static bool
is_thunk_struct(const Struct_type *st);
protected:
int
do_traverse(Traverse* traverse);
......@@ -1023,6 +1027,9 @@ class Thunk_statement : public Statement
void
thunk_field_param(int n, char* buf, size_t buflen);
// A list of all the struct types created for thunk statements.
static Unordered_set(const Struct_type*) thunk_types;
// The function call to be executed in a separate thread (go) or
// later (defer).
Expression* call_;
......
......@@ -1593,7 +1593,9 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
hash_fnname = "__go_type_hash_identity";
equal_fnname = "__go_type_equal_identity";
}
else if (!this->is_comparable())
else if (!this->is_comparable() ||
(this->struct_type() != NULL
&& Thunk_statement::is_thunk_struct(this->struct_type())))
{
hash_fnname = "__go_type_hash_error";
equal_fnname = "__go_type_equal_error";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment