escape: Avoid allocation of varargs parameter.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 6 Oct 2016 03:51:03 +0000 (03:51 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 6 Oct 2016 03:51:03 +0000 (03:51 +0000)
    There was a bug in the escape analysis that would cause
    the slice implicitly created to hold varargs parameters to always
    escape, as well as the appended to slice argument.  The intended
    behavior was that the elements of the appendee and appended to
    slice would escape to the heap.  Alongside of these issues,
    the varargs slice would also have a chance to be initialized to an
    invalid memory location if it were stack-allocated.  This has been
    fixed as well.

    Reviewed-on: https://go-review.googlesource.com/30450

From-SVN: r240826

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/escape.cc

index 1bd4552e6647ffb6efe6956bb6101c48dd4eaa3d..a4dac9935a971a7345817d2f3cc7f74b2256efd1 100644 (file)
@@ -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 1c810769d229fb9e2542e19a0cae500e6aed4543..ba82d8055d4cb87637394c0f6c5f98e7ade0597d 100644 (file)
@@ -1215,7 +1215,7 @@ Escape_analysis_assign::expression(Expression** pexpr)
                             "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(Node* dst, Node* src)
          // 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;
         }