This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Go patch committed: Permit copying hidden fields in method receiver
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Mon, 28 Mar 2011 16:54:36 -0700
- Subject: 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"