aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2015-06-15 22:45:02 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-06-15 22:45:02 +0000
commit0df824fade1ddb1db395ff1340bd24691c2cc821 (patch)
treed6d4ae67acb9431c9181d57a20a864dccbfd4d97 /gcc/go
parent7faaf44a7f673db903e6b85b2d8d30e189622973 (diff)
downloadgcc-0df824fade1ddb1db395ff1340bd24691c2cc821.zip
gcc-0df824fade1ddb1db395ff1340bd24691c2cc821.tar.gz
gcc-0df824fade1ddb1db395ff1340bd24691c2cc821.tar.bz2
escape: Analyze binary expressions.
Binary expressions might contain function calls that cause an object to escape. Previously, there were not analyzed. Reviewed-on: https://go-review.googlesource.com/10660 From-SVN: r224496
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/escape.cc49
2 files changed, 34 insertions, 17 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 51d1bb1..199ba94 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-8eeba3ad318863eea867669609a1910101c23f00
+a5122ab435cf40c22b110487eb5f189ee28e77f4
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 883e69c..d54b7cc 100644
--- a/gcc/go/gofrontend/escape.cc
+++ b/gcc/go/gofrontend/escape.cc
@@ -453,6 +453,11 @@ class Build_connection_graphs : public Traverse
void
handle_composite_literal(Named_object* object, Expression* expr);
+ // Handle analysis of the left and right operands of a binary expression
+ // with respect to OBJECT.
+ void
+ handle_binary(Named_object* object, Expression* expr);
+
// Resolve the outermost named object of EXPR if there is one.
Named_object*
resolve_var_reference(Expression* expr);
@@ -931,6 +936,31 @@ Build_connection_graphs::handle_composite_literal(Named_object* object,
}
}
+// Given an OBJECT reference in a binary expression E, analyze the left and
+// right operands for possible edges.
+
+void
+Build_connection_graphs::handle_binary(Named_object* object, Expression* e)
+{
+ Binary_expression* be = e->binary_expression();
+ go_assert(be != NULL);
+ Expression* left = be->left();
+ Expression* right = be->right();
+
+ if (left->call_result_expression() != NULL)
+ left = left->call_result_expression()->call();
+ if (left->call_expression() != NULL)
+ this->handle_call(object, left);
+ else if (left->binary_expression() != NULL)
+ this->handle_binary(object, left);
+ if (right->call_result_expression() != NULL)
+ right = right->call_result_expression()->call();
+ if (right->call_expression() != NULL)
+ this->handle_call(object, right);
+ else if (right->binary_expression() != NULL)
+ this->handle_binary(object, right);
+}
+
// Create connection nodes for each variable in a called function.
int
@@ -1024,8 +1054,6 @@ Build_connection_graphs::variable(Named_object* var)
|| rhs_no != var)
break;
- var_node->connection_node()->set_escape_state(Node::ESCAPE_ARG);
-
Node* def_node = this->gogo_->add_connection_node(lhs_no);
def_node->add_edge(var_node);
}
@@ -1075,20 +1103,7 @@ Build_connection_graphs::variable(Named_object* var)
if (cond->call_expression() != NULL)
this->handle_call(var, cond);
else if (cond->binary_expression() != NULL)
- {
- Binary_expression* comp = cond->binary_expression();
- Expression* left = comp->left();
- Expression* right = comp->right();
-
- if (left->call_result_expression() != NULL)
- left = left->call_result_expression()->call();
- if (left->call_expression() != NULL)
- this->handle_call(var, left);
- if (right->call_result_expression() != NULL)
- right = right->call_result_expression()->call();
- if (right->call_expression() != NULL)
- this->handle_call(var, right);
- }
+ this->handle_binary(var, cond);
}
break;
@@ -1117,6 +1132,8 @@ Build_connection_graphs::variable(Named_object* var)
init = init->call_result_expression()->call();
if (init->call_expression() != NULL)
this->handle_call(var, init);
+ else if (init->binary_expression() != NULL)
+ this->handle_binary(var, init);
}
break;