aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorChris Manghane <cmang@google.com>2013-10-14 22:52:55 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-10-14 22:52:55 +0000
commitb93e0cfdd185098c4b5bb059afb92e0cbe8f235c (patch)
tree41f23c7bb9722e4a5193e9ae568a92f62eb6da05 /gcc/go
parentbe66a22638ada47b4fdf0b42be1d44e6cd4fe104 (diff)
downloadgcc-b93e0cfdd185098c4b5bb059afb92e0cbe8f235c.zip
gcc-b93e0cfdd185098c4b5bb059afb92e0cbe8f235c.tar.gz
gcc-b93e0cfdd185098c4b5bb059afb92e0cbe8f235c.tar.bz2
runtime: Don't clobber saved context when catching signal.
* go-gcc.cc (Gcc_backend::address_expression): New function. From-SVN: r203579
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/ChangeLog4
-rw-r--r--gcc/go/go-gcc.cc16
-rw-r--r--gcc/go/gofrontend/backend.h4
-rw-r--r--gcc/go/gofrontend/expressions.cc45
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc6
-rw-r--r--gcc/go/gofrontend/types.cc17
-rw-r--r--gcc/go/gofrontend/types.h4
7 files changed, 66 insertions, 30 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 4d0dd11..70f3496 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,7 @@
+2013-10-14 Chris Manghane <cmang@google.com>
+
+ * go-gcc.cc (Gcc_backend::address_expression): New function.
+
2013-10-11 Chris Manghane <cmang@google.com>
* go-gcc.cc (Gcc_backend::function_code_expression): New
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 81e9ad1..5ff529f 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -235,6 +235,9 @@ class Gcc_backend : public Backend
Bexpression*
function_code_expression(Bfunction*, Location);
+ Bexpression*
+ address_expression(Bexpression*, Location);
+
// Statements.
Bstatement*
@@ -997,6 +1000,19 @@ Gcc_backend::function_code_expression(Bfunction* bfunc, Location location)
return this->make_expression(ret);
}
+// Get the address of an expression.
+
+Bexpression*
+Gcc_backend::address_expression(Bexpression* bexpr, Location location)
+{
+ tree expr = bexpr->get_tree();
+ if (expr == error_mark_node)
+ return this->error_expression();
+
+ tree ret = build_fold_addr_expr_loc(location.gcc_location(), expr);
+ return this->make_expression(ret);
+}
+
// An expression as a statement.
Bstatement*
diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h
index ca997f0..6f2c321 100644
--- a/gcc/go/gofrontend/backend.h
+++ b/gcc/go/gofrontend/backend.h
@@ -271,6 +271,10 @@ class Backend
virtual Bexpression*
function_code_expression(Bfunction*, Location) = 0;
+ // Create an expression that takes the address of an expression.
+ virtual Bexpression*
+ address_expression(Bexpression*, Location) = 0;
+
// Statements.
// Create an error statement. This is used for cases which should
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 6ba351e..f46c37f 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -286,7 +286,11 @@ Expression::convert_type_to_interface(Translate_context* context,
// Otherwise it is the interface method table for RHS_TYPE.
tree first_field_value;
if (lhs_is_empty)
- first_field_value = rhs_type->type_descriptor_pointer(gogo, location);
+ {
+ Bexpression* rhs_bexpr =
+ rhs_type->type_descriptor_pointer(gogo, location);
+ first_field_value = expr_to_tree(rhs_bexpr);
+ }
else
{
// Build the interface method table for this interface and this
@@ -457,8 +461,9 @@ Expression::convert_interface_to_interface(Translate_context* context,
if (for_type_guard)
{
// A type assertion fails when converting a nil interface.
- tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo,
- location);
+ Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo,
+ location);
+ tree lhs_type_descriptor = expr_to_tree(lhs_type_expr);
static tree assert_interface_decl;
tree call = Gogo::call_builtin(&assert_interface_decl,
location,
@@ -491,8 +496,10 @@ Expression::convert_interface_to_interface(Translate_context* context,
// type assertion converting nil will always succeed.
go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(field)), "__methods")
== 0);
- tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo,
- location);
+ Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo,
+ location);
+ tree lhs_type_descriptor = expr_to_tree(lhs_type_expr);
+
static tree convert_interface_decl;
tree call = Gogo::call_builtin(&convert_interface_decl,
location,
@@ -546,8 +553,9 @@ Expression::convert_interface_to_type(Translate_context* context,
// Call a function to check that the type is valid. The function
// will panic with an appropriate runtime type error if the type is
// not valid.
-
- tree lhs_type_descriptor = lhs_type->type_descriptor_pointer(gogo, location);
+ Bexpression* lhs_type_expr = lhs_type->type_descriptor_pointer(gogo,
+ location);
+ tree lhs_type_descriptor = expr_to_tree(lhs_type_expr);
if (!DECL_P(rhs_tree))
rhs_tree = save_expr(rhs_tree);
@@ -556,8 +564,9 @@ Expression::convert_interface_to_type(Translate_context* context,
Expression::get_interface_type_descriptor(context, rhs_type, rhs_tree,
location);
- tree rhs_inter_descriptor = rhs_type->type_descriptor_pointer(gogo,
- location);
+ Bexpression* rhs_inter_expr = rhs_type->type_descriptor_pointer(gogo,
+ location);
+ tree rhs_inter_descriptor = expr_to_tree(rhs_inter_expr);
static tree check_interface_type_decl;
tree call = Gogo::call_builtin(&check_interface_type_decl,
@@ -6500,8 +6509,9 @@ Expression::comparison_tree(Translate_context* context, Type* result_type,
}
arg = fold_convert_loc(location.gcc_location(), ptr_type_node, arg);
- tree descriptor = right_type->type_descriptor_pointer(context->gogo(),
- location);
+ Bexpression* descriptor_bexpr =
+ right_type->type_descriptor_pointer(context->gogo(), location);
+ tree descriptor = expr_to_tree(descriptor_bexpr);
if (left_type->interface_type()->is_empty())
{
@@ -13256,7 +13266,8 @@ Map_construction_expression::do_get_tree(Translate_context* context)
valaddr = build_fold_addr_expr(tmp);
}
- tree descriptor = mt->map_descriptor_pointer(gogo, loc);
+ Bexpression* bdescriptor = mt->map_descriptor_pointer(gogo, loc);
+ tree descriptor = expr_to_tree(bdescriptor);
tree type_tree = type_to_tree(this->type_->get_backend(gogo));
if (type_tree == error_mark_node)
@@ -14312,8 +14323,9 @@ class Type_descriptor_expression : public Expression
tree
do_get_tree(Translate_context* context)
{
- return this->type_->type_descriptor_pointer(context->gogo(),
- this->location());
+ Bexpression* ret = this->type_->type_descriptor_pointer(context->gogo(),
+ this->location());
+ return expr_to_tree(ret);
}
void
@@ -14568,8 +14580,9 @@ class Map_descriptor_expression : public Expression
tree
do_get_tree(Translate_context* context)
{
- return this->type_->map_descriptor_pointer(context->gogo(),
- this->location());
+ Bexpression* ret = this->type_->map_descriptor_pointer(context->gogo(),
+ this->location());
+ return expr_to_tree(ret);
}
void
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index ca80869..3793b83 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -2107,8 +2107,10 @@ Gogo::interface_method_table_for_type(const Interface_type* interface,
td_type = type;
else
td_type = Type::make_pointer_type(type);
- tree tdp = td_type->type_descriptor_pointer(this,
- Linemap::predeclared_location());
+
+ Location loc = Linemap::predeclared_location();
+ Bexpression* tdp_bexpr = td_type->type_descriptor_pointer(this, loc);
+ tree tdp = expr_to_tree(tdp_bexpr);
elt->value = fold_convert(const_ptr_type_node, tdp);
Named_type* nt = type->named_type();
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 40b62f4..7d808ca 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1204,7 +1204,7 @@ Type::finish_backend(Gogo* gogo, Btype *placeholder)
// Return a pointer to the type descriptor for this type.
-tree
+Bexpression*
Type::type_descriptor_pointer(Gogo* gogo, Location location)
{
Type* t = this->forwarded();
@@ -1215,10 +1215,9 @@ Type::type_descriptor_pointer(Gogo* gogo, Location location)
t->make_type_descriptor_var(gogo);
go_assert(t->type_descriptor_var_ != NULL);
}
- tree var_tree = var_to_tree(t->type_descriptor_var_);
- if (var_tree == error_mark_node)
- return error_mark_node;
- return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
+ Bexpression* var_expr =
+ gogo->backend()->var_expression(t->type_descriptor_var_, location);
+ return gogo->backend()->address_expression(var_expr, location);
}
// A mapping from unnamed types to type descriptor variables.
@@ -6250,14 +6249,12 @@ Map_type::Map_descriptors Map_type::map_descriptors;
// Build a map descriptor for this type. Return a pointer to it.
-tree
+Bexpression*
Map_type::map_descriptor_pointer(Gogo* gogo, Location location)
{
Bvariable* bvar = this->map_descriptor(gogo);
- tree var_tree = var_to_tree(bvar);
- if (var_tree == error_mark_node)
- return error_mark_node;
- return build_fold_addr_expr_loc(location.gcc_location(), var_tree);
+ Bexpression* var_expr = gogo->backend()->var_expression(bvar, location);
+ return gogo->backend()->address_expression(var_expr, location);
}
// Build a map descriptor for this type.
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 928c593..131c9de 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -901,7 +901,7 @@ class Type
// Build a type descriptor entry for this type. Return a pointer to
// it. The location is the location which causes us to need the
// entry.
- tree
+ Bexpression*
type_descriptor_pointer(Gogo* gogo, Location);
// Return the type reflection string for this type.
@@ -2401,7 +2401,7 @@ class Map_type : public Type
// Build a map descriptor for this type. Return a pointer to it.
// The location is the location which causes us to need the
// descriptor.
- tree
+ Bexpression*
map_descriptor_pointer(Gogo* gogo, Location);
protected: