aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2014-12-16 22:53:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2014-12-16 22:53:38 +0000
commite0d475db10f8976060a964517a64cd7b4508cefa (patch)
tree745f7d8d71a7a467de39d8220fc043eb29373144 /gcc
parentc0f15a3f249fa7ec0a210e540c0d3af7f642ccfa (diff)
downloadgcc-e0d475db10f8976060a964517a64cd7b4508cefa.zip
gcc-e0d475db10f8976060a964517a64cd7b4508cefa.tar.gz
gcc-e0d475db10f8976060a964517a64cd7b4508cefa.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/statements.cc17
-rw-r--r--gcc/go/gofrontend/statements.h7
-rw-r--r--gcc/go/gofrontend/types.cc4
3 files changed, 26 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 6eb0d7b..e8c3a3e 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -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
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index 9bb0fb5..e12f60f 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -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_;
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 6533cd4..fbcce7f 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -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";