aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-10-06 03:51:03 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-10-06 03:51:03 +0000
commita7773b4d0629c6ab0d8321c9b018f6a718bf232a (patch)
tree77833c482521ede307d11d30420a0d8a13b0d313
parentf779aeb8af7def1bb21eade301d546fe0297d9e6 (diff)
downloadgcc-a7773b4d0629c6ab0d8321c9b018f6a718bf232a.zip
gcc-a7773b4d0629c6ab0d8321c9b018f6a718bf232a.tar.gz
gcc-a7773b4d0629c6ab0d8321c9b018f6a718bf232a.tar.bz2
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
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/escape.cc32
2 files changed, 32 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1bd4552..a4dac99 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -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.
diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc
index 1c81076..ba82d80 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;
}