This patch by Chris Manghane fixes a bug in the escape analysis pass
of the Go frontend.  The slice created to hold the values passed to a
varargs parameter would always escape.  This also fixes a bug in which
a stack-allocated varargs parameter was incorrectly initialized in
some cases.  Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.
Committed to mainline.

Ian
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE     (revision 240755)
+++ gcc/go/gofrontend/MERGE     (working copy)
@@ -1,4 +1,4 @@
-325f8074c5224ae537f8e00aede5c780b70f914c
+60b84be3fa146d821dcd3939dad6336c89432cff
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/escape.cc
===================================================================
--- gcc/go/gofrontend/escape.cc (revision 240755)
+++ gcc/go/gofrontend/escape.cc (working copy)
@@ -1215,7 +1215,7 @@ Escape_analysis_assign::expression(Expre
                             "special treatment of append(slice1, slice2...)");
 
                  // The content of the original slice leaks as well.
-                 Node* appendee = Node::make_node(call->args()->back());
+                 Node* appendee = Node::make_node(call->args()->front());
                  this->assign_deref(this->context_->sink(), appendee);
                }
                break;
@@ -2088,6 +2088,36 @@ Escape_analysis_assign::assign_deref(Nod
          // or numeric constants.
          return;
 
+       case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
+       case Expression::EXPRESSION_SLICE_CONSTRUCTION:
+       case Expression::EXPRESSION_STRUCT_CONSTRUCTION:
+         {
+           // Dereferencing an array, slice, or struct is like accessing each
+           // of its values.  In this situation, we model the flow from src to
+           // dst where src is one of the above as a flow from each of src's
+           // values to dst.
+           Expression* e = src->expr();
+           Expression_list* vals = NULL;
+           if (e->slice_literal() != NULL)
+             vals = e->slice_literal()->vals();
+           else if (e->array_literal() != NULL)
+             vals = e->array_literal()->vals();
+           else
+             vals = e->struct_literal()->vals();
+
+           if (vals != NULL)
+             {
+               for (Expression_list::const_iterator p = vals->begin();
+                    p != vals->end();
+                    ++p)
+                 {
+                   if ((*p) != NULL)
+                     this->assign(dst, Node::make_node(*p));
+                 }
+             }
+         }
+         return;
+
        default:
          break;
         }

Reply via email to