aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/go-gcc.cc
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2018-01-09 21:33:59 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-09 21:33:59 +0000
commit81e0f09288052014c5fb3136e6abc9dfcc7629db (patch)
treed85e4d07a55f301cdce0f9af88f503c2cc802899 /gcc/go/go-gcc.cc
parent6ef72c3661318d0b5d7e3fc8821d136bbba37194 (diff)
downloadgcc-81e0f09288052014c5fb3136e6abc9dfcc7629db.zip
gcc-81e0f09288052014c5fb3136e6abc9dfcc7629db.tar.gz
gcc-81e0f09288052014c5fb3136e6abc9dfcc7629db.tar.bz2
compiler: make top-level decl for address-taken non-escaping locals
If a local variable's address is taken and passed out of its lexical scope, GCC backend may reuse the stack slot for the variable, not knowing it is still live through a pointer. In this case, we create a top-level temporary variable and let the user-defined variable refer to the temporary variable as its storage location. As the temporary variable is declared at the top level, its stack slot will remain live throughout the function. Reviewed-on: https://go-review.googlesource.com/84675 * go-gcc.cc (local_variable): Add decl_var parameter. From-SVN: r256398
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r--gcc/go/go-gcc.cc11
1 files changed, 8 insertions, 3 deletions
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 7c78602..9bc049e 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -426,7 +426,7 @@ class Gcc_backend : public Backend
global_variable_set_init(Bvariable*, Bexpression*);
Bvariable*
- local_variable(Bfunction*, const std::string&, Btype*, bool,
+ local_variable(Bfunction*, const std::string&, Btype*, Bvariable*, bool,
Location);
Bvariable*
@@ -2584,8 +2584,8 @@ Gcc_backend::global_variable_set_init(Bvariable* var, Bexpression* expr)
Bvariable*
Gcc_backend::local_variable(Bfunction* function, const std::string& name,
- Btype* btype, bool is_address_taken,
- Location location)
+ Btype* btype, Bvariable* decl_var,
+ bool is_address_taken, Location location)
{
tree type_tree = btype->get_tree();
if (type_tree == error_mark_node)
@@ -2597,6 +2597,11 @@ Gcc_backend::local_variable(Bfunction* function, const std::string& name,
TREE_USED(decl) = 1;
if (is_address_taken)
TREE_ADDRESSABLE(decl) = 1;
+ if (decl_var != NULL)
+ {
+ DECL_HAS_VALUE_EXPR_P(decl) = 1;
+ SET_DECL_VALUE_EXPR(decl, decl_var->get_decl());
+ }
go_preserve_from_gc(decl);
return new Bvariable(decl);
}