This patch to the Go compiler reliably gives an error on a misuse of a
function call that returns multiple values.  Previously this could
eventually lead to a compiler crash.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

diff -r afc75dd8b19a go/types.cc
--- a/go/types.cc	Thu Mar 01 09:21:27 2012 -0800
+++ b/go/types.cc	Thu Mar 01 10:17:10 2012 -0800
@@ -622,16 +622,24 @@
 				  std::string* reason)
 {
   // Do some checks first.  Make sure the types are defined.
-  if (rhs != NULL
-      && rhs->forwarded()->forward_declaration_type() == NULL
-      && rhs->is_void_type())
-    {
-      if (reason != NULL)
-	*reason = "non-value used as value";
-      return false;
-    }
-
-  if (lhs != NULL && lhs->forwarded()->forward_declaration_type() == NULL)
+  if (rhs != NULL && !rhs->is_undefined())
+    {
+      if (rhs->is_void_type())
+	{
+	  if (reason != NULL)
+	    *reason = "non-value used as value";
+	  return false;
+	}
+      if (rhs->is_call_multiple_result_type())
+	{
+	  if (reason != NULL)
+	    reason->assign(_("multiple value function call in "
+			     "single value context"));
+	  return false;
+	}
+    }
+
+  if (lhs != NULL && !lhs->is_undefined())
     {
       // Any value may be assigned to the blank identifier.
       if (lhs->is_sink_type())
@@ -639,9 +647,7 @@
 
       // All fields of a struct must be exported, or the assignment
       // must be in the same package.
-      if (check_hidden_fields
-	  && rhs != NULL
-	  && rhs->forwarded()->forward_declaration_type() == NULL)
+      if (check_hidden_fields && rhs != NULL && !rhs->is_undefined())
 	{
 	  if (lhs->has_hidden_fields(NULL, reason)
 	      || rhs->has_hidden_fields(NULL, reason))
@@ -715,9 +721,6 @@
     {
       if (rhs->interface_type() != NULL)
 	reason->assign(_("need explicit conversion"));
-      else if (rhs->is_call_multiple_result_type())
-	reason->assign(_("multiple value function call in "
-			 "single value context"));
       else if (lhs->named_type() != NULL && rhs->named_type() != NULL)
 	{
 	  size_t len = (lhs->named_type()->name().length()

Reply via email to