summaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/escape.cc
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-06 03:51:03 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-06 03:51:03 +0000
commit08c7f1a976308b1002ab9ee0531af976b8d9f7db (patch)
tree77833c482521ede307d11d30420a0d8a13b0d313 /gcc/go/gofrontend/escape.cc
parentbb513366944d86180b099fd61c8f555282d528a7 (diff)
downloadgcc-08c7f1a976308b1002ab9ee0531af976b8d9f7db.tar.gz
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 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240826 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go/gofrontend/escape.cc')
-rw-r--r--gcc/go/gofrontend/escape.cc32
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc
index 1c810769d22..ba82d8055d4 100644
--- a/gcc/go/gofrontend/escape.cc
+++ b/gcc/go/gofrontend/escape.cc
@@ -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;
}