compiler: Don't built hash/equality functions for thunk structs.
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 16 Dec 2014 22:53:38 +0000 (22:53 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 16 Dec 2014 22:53:38 +0000 (22:53 +0000)
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

gcc/go/gofrontend/statements.cc
gcc/go/gofrontend/statements.h
gcc/go/gofrontend/types.cc

index 6eb0d7bcc78991e3bdfd8c4153d36f1af5ab3704..e8c3a3e27023e2968666882d227645b8b561f4d3 100644 (file)
@@ -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
index 9bb0fb5aa8df0de3c471777175804f4cb12da290..e12f60fdd30c11f726796458c8a72a50918c3d60 100644 (file)
@@ -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_;
index 6533cd46ea2977a27b2110cefb1a6f68eb86e646..fbcce7f3ed601726b48e9d12e881d1882641a31a 100644 (file)
@@ -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";