Commit a7773b4d by Ian Lance Taylor

escape: Avoid allocation of varargs parameter.

    
    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
parent f779aeb8
325f8074c5224ae537f8e00aede5c780b70f914c
60b84be3fa146d821dcd3939dad6336c89432cff
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment