This patch from Chris Manghane changes the Go frontend to use allocate for non-escaping new expressions. Previously it was using a temporary variable, which failed when the new expression was in a loop. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian 2015-04-30 Chris Manghane <cm...@google.com> * go-gcc.cc (Gcc_backend::stack_allocation_expression): New method.
Index: go-gcc.cc =================================================================== --- go-gcc.cc (revision 222656) +++ go-gcc.cc (working copy) @@ -324,6 +324,9 @@ class Gcc_backend : public Backend call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, Bexpression* static_chain, Location); + Bexpression* + stack_allocation_expression(int64_t size, Location); + // Statements. Bstatement* @@ -1884,6 +1887,17 @@ Gcc_backend::call_expression(Bexpression return this->make_expression(ret); } +// Return an expression that allocates SIZE bytes on the stack. + +Bexpression* +Gcc_backend::stack_allocation_expression(int64_t size, Location location) +{ + tree alloca = builtin_decl_explicit(BUILT_IN_ALLOCA); + tree size_tree = build_int_cst(integer_type_node, size); + tree ret = build_call_expr_loc(location.gcc_location(), alloca, 1, size_tree); + return this->make_expression(ret); +} + // An expression as a statement. Bstatement* Index: gofrontend/backend.h =================================================================== --- gofrontend/backend.h (revision 222656) +++ gofrontend/backend.h (working copy) @@ -377,6 +377,10 @@ class Backend call_expression(Bexpression* fn, const std::vector<Bexpression*>& args, Bexpression* static_chain, Location) = 0; + // Return an expression that allocates SIZE bytes on the stack. + virtual Bexpression* + stack_allocation_expression(int64_t size, Location) = 0; + // Statements. // Create an error statement. This is used for cases which should Index: gofrontend/expressions.cc =================================================================== --- gofrontend/expressions.cc (revision 222656) +++ gofrontend/expressions.cc (working copy) @@ -11428,20 +11428,6 @@ Allocation_expression::do_copy() return alloc; } -Expression* -Allocation_expression::do_flatten(Gogo*, Named_object*, - Statement_inserter* inserter) -{ - if (this->allocate_on_stack_) - { - this->stack_temp_ = Statement::make_temporary(this->type_, NULL, - this->location()); - this->stack_temp_->set_is_address_taken(); - inserter->insert(this->stack_temp_); - } - return this; -} - // Return the backend representation for an allocation expression. Bexpression* @@ -11450,17 +11436,16 @@ Allocation_expression::do_get_backend(Tr Gogo* gogo = context->gogo(); Location loc = this->location(); - if (this->stack_temp_ != NULL) + Btype* btype = this->type_->get_backend(gogo); + if (this->allocate_on_stack_) { - Expression* ref = - Expression::make_temporary_reference(this->stack_temp_, loc); - ref = Expression::make_unary(OPERATOR_AND, ref, loc); - return ref->get_backend(context); + int64_t size = gogo->backend()->type_size(btype); + return gogo->backend()->stack_allocation_expression(size, loc); } Bexpression* space = gogo->allocate_memory(this->type_, loc)->get_backend(context); - Btype* pbtype = gogo->backend()->pointer_type(this->type_->get_backend(gogo)); + Btype* pbtype = gogo->backend()->pointer_type(btype); return gogo->backend()->convert_expression(pbtype, space, loc); } Index: gofrontend/expressions.h =================================================================== --- gofrontend/expressions.h (revision 222656) +++ gofrontend/expressions.h (working copy) @@ -2786,7 +2786,7 @@ class Allocation_expression : public Exp public: Allocation_expression(Type* type, Location location) : Expression(EXPRESSION_ALLOCATION, location), - type_(type), allocate_on_stack_(false), stack_temp_(NULL) + type_(type), allocate_on_stack_(false) { } void @@ -2807,9 +2807,6 @@ class Allocation_expression : public Exp Expression* do_copy(); - Expression* - do_flatten(Gogo*, Named_object*, Statement_inserter*); - Bexpression* do_get_backend(Translate_context*); @@ -2821,9 +2818,6 @@ class Allocation_expression : public Exp Type* type_; // Whether or not this is a stack allocation. bool allocate_on_stack_; - // If this memory is stack allocated, it will use the address of STACK_TEMP. - // Otherwise, STACK_TEMP is NULL. - Temporary_statement* stack_temp_; }; // Construct a struct.