This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Go patch committed: Permit copying hidden fields in method receiver


The Go language now permits copying hidden fields when passing a value
to a method receiver.  This patch implements that in gccgo.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

diff -r ea8e140e8fab go/expressions.cc
--- a/go/expressions.cc	Mon Mar 28 16:12:27 2011 -0700
+++ b/go/expressions.cc	Mon Mar 28 16:51:23 2011 -0700
@@ -8558,10 +8558,11 @@
       if (first_arg_type->points_to() == NULL)
 	{
 	  // When passing a value, we need to check that we are
-	  // permitted to copy it.
+	  // permitted to copy it.  The language permits copying
+	  // hidden fields for a method receiver.
 	  std::string reason;
-	  if (!Type::are_assignable(fntype->receiver()->type(),
-				    first_arg_type, &reason))
+	  if (!Type::are_assignable_hidden_ok(fntype->receiver()->type(),
+					      first_arg_type, &reason))
 	    {
 	      if (reason.empty())
 		this->report_error(_("incompatible type for receiver"));
diff -r ea8e140e8fab go/types.cc
--- a/go/types.cc	Mon Mar 28 16:12:27 2011 -0700
+++ b/go/types.cc	Mon Mar 28 16:51:23 2011 -0700
@@ -475,11 +475,14 @@
 }
 
 // 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.
+// 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.
 
 bool
-Type::are_assignable(const Type* lhs, const Type* rhs, std::string* reason)
+Type::are_assignable_check_hidden(const Type* lhs, const Type* rhs,
+				  bool check_hidden_fields,
+				  std::string* reason)
 {
   // Do some checks first.  Make sure the types are defined.
   if (rhs != NULL
@@ -499,7 +502,9 @@
 
       // All fields of a struct must be exported, or the assignment
       // must be in the same package.
-      if (rhs != NULL && rhs->forwarded()->forward_declaration_type() == NULL)
+      if (check_hidden_fields
+	  && rhs != NULL
+	  && rhs->forwarded()->forward_declaration_type() == NULL)
 	{
 	  if (lhs->has_hidden_fields(NULL, reason)
 	      || rhs->has_hidden_fields(NULL, reason))
@@ -593,6 +598,25 @@
   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, true, 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.
diff -r ea8e140e8fab go/types.h
--- a/go/types.h	Mon Mar 28 16:12:27 2011 -0700
+++ b/go/types.h	Mon Mar 28 16:51:23 2011 -0700
@@ -521,6 +521,14 @@
   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.
@@ -1011,6 +1019,11 @@
 	    : 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);
+
   // Get the hash and equality functions for a type.
   void
   type_functions(const char** hash_fn, const char** equal_fn) const;
Index: gcc/testsuite/go.test/test/fixedbugs/bug226.dir/y.go
===================================================================
--- gcc/testsuite/go.test/test/fixedbugs/bug226.dir/y.go	(revision 171576)
+++ gcc/testsuite/go.test/test/fixedbugs/bug226.dir/y.go	(working copy)
@@ -15,7 +15,7 @@ func f() {
 	_ = x.T{};
 	_ = x.T{Y:2};
 	
-	ok1.M();	// ERROR "assignment.*T"
+	ok1.M();
 	bad1 := *ok;	// ERROR "assignment.*T"
 	bad2 := ok1;	// ERROR "assignment.*T"
 	*ok4 = ok1;	// ERROR "assignment.*T"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]