mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
f779aeb8af
commit
a7773b4d06
|
|
@ -1,4 +1,4 @@
|
||||||
325f8074c5224ae537f8e00aede5c780b70f914c
|
60b84be3fa146d821dcd3939dad6336c89432cff
|
||||||
|
|
||||||
The first line of this file holds the git revision number of the last
|
The first line of this file holds the git revision number of the last
|
||||||
merge done from the gofrontend repository.
|
merge done from the gofrontend repository.
|
||||||
|
|
|
||||||
|
|
@ -1215,7 +1215,7 @@ Escape_analysis_assign::expression(Expression** pexpr)
|
||||||
"special treatment of append(slice1, slice2...)");
|
"special treatment of append(slice1, slice2...)");
|
||||||
|
|
||||||
// The content of the original slice leaks as well.
|
// 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);
|
this->assign_deref(this->context_->sink(), appendee);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2088,6 +2088,36 @@ Escape_analysis_assign::assign_deref(Node* dst, Node* src)
|
||||||
// or numeric constants.
|
// or numeric constants.
|
||||||
return;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue