This patch to the Go frontend by Than McIntosh removes the LHS/RHS context determination for variable references. It used to be needed for a different backend but it's no longer necessary. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian 2017-11-14 Than McIntosh <th...@google.com> * go-gcc.cc (var_expression): Remove Varexpr_context parameter.
Index: gcc/go/go-gcc.cc =================================================================== --- gcc/go/go-gcc.cc (revision 254090) +++ gcc/go/go-gcc.cc (working copy) @@ -276,7 +276,7 @@ class Gcc_backend : public Backend { return this->make_expression(null_pointer_node); } Bexpression* - var_expression(Bvariable* var, Varexpr_context, Location); + var_expression(Bvariable* var, Location); Bexpression* indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location); @@ -1256,7 +1256,7 @@ Gcc_backend::zero_expression(Btype* btyp // An expression that references a variable. Bexpression* -Gcc_backend::var_expression(Bvariable* var, Varexpr_context, Location location) +Gcc_backend::var_expression(Bvariable* var, Location location) { tree ret = var->get_tree(location); if (ret == error_mark_node) Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 254729) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -d028451131e92bab5379defb04ead87ca978ed25 +cb5dc1ce98857884a2215c461dd1d7de530f9f5e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/backend.h =================================================================== --- gcc/go/gofrontend/backend.h (revision 254090) +++ gcc/go/gofrontend/backend.h (working copy) @@ -254,7 +254,7 @@ class Backend // Create a reference to a variable. virtual Bexpression* - var_expression(Bvariable* var, Varexpr_context in_lvalue_pos, Location) = 0; + var_expression(Bvariable* var, Location) = 0; // Create an expression that indirects through the pointer expression EXPR // (i.e., return the expression for *EXPR). KNOWN_VALID is true if the pointer Index: gcc/go/gofrontend/expressions.cc =================================================================== --- gcc/go/gofrontend/expressions.cc (revision 254126) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -771,7 +771,7 @@ Var_expression::do_get_backend(Translate go_unreachable(); Bexpression* ret = - context->backend()->var_expression(bvar, this->in_lvalue_pos_, loc); + context->backend()->var_expression(bvar, loc); if (is_in_heap) ret = context->backend()->indirect_expression(btype, ret, true, loc); return ret; @@ -898,10 +898,7 @@ Temporary_reference_expression::do_get_b { Gogo* gogo = context->gogo(); Bvariable* bvar = this->statement_->get_backend_variable(context); - Varexpr_context ve_ctxt = (this->is_lvalue_ ? VE_lvalue : VE_rvalue); - - Bexpression* ret = gogo->backend()->var_expression(bvar, ve_ctxt, - this->location()); + Bexpression* ret = gogo->backend()->var_expression(bvar, this->location()); // The backend can't always represent the same set of recursive types // that the Go frontend can. In some cases this means that a @@ -972,7 +969,7 @@ Set_and_use_temporary_expression::do_get Location loc = this->location(); Gogo* gogo = context->gogo(); Bvariable* bvar = this->statement_->get_backend_variable(context); - Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, VE_lvalue, loc); + Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, loc); Named_object* fn = context->function(); go_assert(fn != NULL); @@ -980,7 +977,7 @@ Set_and_use_temporary_expression::do_get Bexpression* bexpr = this->expr_->get_backend(context); Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref, bexpr, loc); - Bexpression* var_ref = gogo->backend()->var_expression(bvar, VE_rvalue, loc); + Bexpression* var_ref = gogo->backend()->var_expression(bvar, loc); Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc); return ret; } @@ -1084,11 +1081,11 @@ Sink_expression::do_get_backend(Translat gogo->backend()->temporary_variable(fn_ctx, context->bblock(), bt, NULL, false, loc, &decl); Bexpression* var_ref = - gogo->backend()->var_expression(this->bvar_, VE_lvalue, loc); + gogo->backend()->var_expression(this->bvar_, loc); var_ref = gogo->backend()->compound_expression(decl, var_ref, loc); return var_ref; } - return gogo->backend()->var_expression(this->bvar_, VE_lvalue, loc); + return gogo->backend()->var_expression(this->bvar_, loc); } // Ast dump for sink expression. @@ -1302,7 +1299,7 @@ Func_descriptor_expression::do_get_backe Named_object* no = this->fn_; Location loc = no->location(); if (this->dvar_ != NULL) - return context->backend()->var_expression(this->dvar_, VE_rvalue, loc); + return context->backend()->var_expression(this->dvar_, loc); Gogo* gogo = context->gogo(); std::string var_name(gogo->function_descriptor_name(no)); @@ -1340,7 +1337,7 @@ Func_descriptor_expression::do_get_backe } this->dvar_ = bvar; - return gogo->backend()->var_expression(bvar, VE_rvalue, loc); + return gogo->backend()->var_expression(bvar, loc); } // Print a function descriptor expression. @@ -4286,7 +4283,7 @@ Unary_expression::do_get_backend(Transla Temporary_statement* temp = sut->temporary(); Bvariable* bvar = temp->get_backend_variable(context); Bexpression* bvar_expr = - gogo->backend()->var_expression(bvar, VE_lvalue, loc); + gogo->backend()->var_expression(bvar, loc); Bexpression* bval = sut->expression()->get_backend(context); Named_object* fn = context->function(); @@ -4373,7 +4370,7 @@ Unary_expression::do_get_backend(Transla gogo->backend()->implicit_variable_set_init(implicit, var_name, btype, true, copy_to_heap, false, bexpr); - bexpr = gogo->backend()->var_expression(implicit, VE_rvalue, loc); + bexpr = gogo->backend()->var_expression(implicit, loc); // If we are not copying a slice initializer to the heap, // then it can be changed by the program, so if it can @@ -4383,7 +4380,7 @@ Unary_expression::do_get_backend(Transla && this->expr_->type()->has_pointer()) { Bexpression* root = - gogo->backend()->var_expression(implicit, VE_rvalue, loc); + gogo->backend()->var_expression(implicit, loc); root = gogo->backend()->address_expression(root, loc); Type* type = Type::make_pointer_type(this->expr_->type()); gogo->add_gc_root(Expression::make_backend(root, type, loc)); @@ -4400,7 +4397,7 @@ Unary_expression::do_get_backend(Transla true, false, btype, loc); gogo->backend()->immutable_struct_set_init(decl, var_name, true, false, btype, loc, bexpr); - bexpr = gogo->backend()->var_expression(decl, VE_rvalue, loc); + bexpr = gogo->backend()->var_expression(decl, loc); } go_assert(!this->create_temp_ || this->expr_->is_variable()); @@ -14309,7 +14306,7 @@ Heap_expression::do_get_backend(Translat Bstatement* assn; if (!etype->has_pointer()) { - space = gogo->backend()->var_expression(space_temp, VE_lvalue, loc); + space = gogo->backend()->var_expression(space_temp, loc); Bexpression* ref = gogo->backend()->indirect_expression(expr_btype, space, true, loc); assn = gogo->backend()->assignment_statement(fndecl, ref, bexpr, loc); @@ -14322,12 +14319,12 @@ Heap_expression::do_get_backend(Translat expr_btype, bexpr, true, loc, &edecl); Bexpression* btempref = gogo->backend()->var_expression(btemp, - VE_lvalue, loc); + loc); Bexpression* addr = gogo->backend()->address_expression(btempref, loc); Expression* td = Expression::make_type_descriptor(etype, loc); Type* etype_ptr = Type::make_pointer_type(etype); - space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc); + space = gogo->backend()->var_expression(space_temp, loc); Expression* elhs = Expression::make_backend(space, etype_ptr, loc); Expression* erhs = Expression::make_backend(addr, etype_ptr, loc); Expression* call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3, @@ -14337,7 +14334,7 @@ Heap_expression::do_get_backend(Translat assn = gogo->backend()->compound_statement(edecl, s); } decl = gogo->backend()->compound_statement(decl, assn); - space = gogo->backend()->var_expression(space_temp, VE_rvalue, loc); + space = gogo->backend()->var_expression(space_temp, loc); return gogo->backend()->compound_expression(decl, space, loc); } @@ -14661,7 +14658,7 @@ Ptrmask_symbol_expression::do_get_backen Bvariable* bvar = this->type_->gc_ptrmask_var(gogo, ptrsize, ptrdata); Location bloc = Linemap::predeclared_location(); - Bexpression* bref = gogo->backend()->var_expression(bvar, VE_rvalue, bloc); + Bexpression* bref = gogo->backend()->var_expression(bvar, bloc); Bexpression* baddr = gogo->backend()->address_expression(bref, bloc); Type* uint8_type = Type::lookup_integer_type("uint8"); @@ -15380,8 +15377,7 @@ Interface_mtable_expression::do_get_back Gogo* gogo = context->gogo(); Location loc = Linemap::predeclared_location(); if (this->bvar_ != NULL) - return gogo->backend()->var_expression(this->bvar_, VE_rvalue, - this->location()); + return gogo->backend()->var_expression(this->bvar_, this->location()); const Typed_identifier_list* interface_methods = this->itype_->methods(); go_assert(!interface_methods->empty()); @@ -15421,8 +15417,7 @@ Interface_mtable_expression::do_get_back this->bvar_ = gogo->backend()->immutable_struct_reference(mangled_name, asm_name, btype, loc); - return gogo->backend()->var_expression(this->bvar_, VE_rvalue, - this->location()); + return gogo->backend()->var_expression(this->bvar_, this->location()); } // The first element is the type descriptor. @@ -15487,7 +15482,7 @@ Interface_mtable_expression::do_get_back !is_public, btype, loc); gogo->backend()->immutable_struct_set_init(this->bvar_, mangled_name, false, !is_public, btype, loc, ctor); - return gogo->backend()->var_expression(this->bvar_, VE_lvalue, loc); + return gogo->backend()->var_expression(this->bvar_, loc); } void Index: gcc/go/gofrontend/expressions.h =================================================================== --- gcc/go/gofrontend/expressions.h (revision 254090) +++ gcc/go/gofrontend/expressions.h (working copy) @@ -1298,7 +1298,7 @@ class Var_expression : public Expression public: Var_expression(Named_object* variable, Location location) : Expression(EXPRESSION_VAR_REFERENCE, location), - variable_(variable), in_lvalue_pos_(VE_rvalue) + variable_(variable) { } // Return the variable. @@ -1306,16 +1306,6 @@ class Var_expression : public Expression named_object() const { return this->variable_; } - // Does this var expression appear in an lvalue (assigned-to) context? - bool - in_lvalue_pos() const - { return this->in_lvalue_pos_ == VE_lvalue; } - - // Mark a var_expression as appearing in an lvalue context. - void - set_in_lvalue_pos() - { this->in_lvalue_pos_ = VE_lvalue; } - protected: Expression* do_lower(Gogo*, Named_object*, Statement_inserter*, int); @@ -1346,8 +1336,6 @@ class Var_expression : public Expression private: // The variable we are referencing. Named_object* variable_; - // Set to TRUE if var expression appears in lvalue context - Varexpr_context in_lvalue_pos_; }; // A reference to a variable within an enclosing function. Index: gcc/go/gofrontend/gogo.cc =================================================================== --- gcc/go/gofrontend/gogo.cc (revision 254090) +++ gcc/go/gofrontend/gogo.cc (working copy) @@ -1394,7 +1394,7 @@ Gogo::write_globals() { Location loc = var->location(); Bexpression* var_expr = - this->backend()->var_expression(bvar, VE_lvalue, loc); + this->backend()->var_expression(bvar, loc); var_init_stmt = this->backend()->assignment_statement(init_bfn, var_expr, var_binit, loc); @@ -5798,8 +5798,7 @@ Function::return_value(Gogo* gogo, Named { Named_object* no = (*this->results_)[i]; Bvariable* bvar = no->get_backend_variable(gogo, named_function); - Bexpression* val = gogo->backend()->var_expression(bvar, VE_rvalue, - location); + Bexpression* val = gogo->backend()->var_expression(bvar, location); if (no->result_var_value()->is_in_heap()) { Btype* bt = no->result_var_value()->type()->get_backend(gogo); @@ -6632,7 +6631,7 @@ Variable::get_init_block(Gogo* gogo, Nam Expression::make_cast(this->type(), this->init_, loc); Bexpression* val = val_expr->get_backend(&context); Bexpression* var_ref = - gogo->backend()->var_expression(var_decl, VE_lvalue, loc); + gogo->backend()->var_expression(var_decl, loc); decl_init = gogo->backend()->assignment_statement(bfunction, var_ref, val, loc); } Index: gcc/go/gofrontend/operator.h =================================================================== --- gcc/go/gofrontend/operator.h (revision 254090) +++ gcc/go/gofrontend/operator.h (working copy) @@ -63,10 +63,4 @@ enum Operator OPERATOR_RSQUARE // ] }; -// Whether a variable expression appears in lvalue (assignment) context. -enum Varexpr_context { - VE_rvalue, - VE_lvalue -}; - #endif // !defined(GO_OPERATOR_H) Index: gcc/go/gofrontend/statements.cc =================================================================== --- gcc/go/gofrontend/statements.cc (revision 254090) +++ gcc/go/gofrontend/statements.cc (working copy) @@ -836,100 +836,6 @@ Assignment_statement::do_flatten(Gogo*, return this; } - -// Helper class to locate a root Var_expression within an expression -// tree and mark it as being in an "lvalue" or assignment -// context. Examples: -// -// x, y = 40, foo(w) -// x[2] = bar(v) -// x.z.w[blah(v + u)], y.another = 2, 3 -// -// In the code above, vars "x" and "y" appear in lvalue / assignment -// context, whereas the other vars "v", "u", etc are in rvalue context. -// -// Note: at the moment the Var_expression version of "do_copy()" -// defaults to returning the original object, not a new object, -// meaning that a given Var_expression can be referenced from more -// than one place in the tree. This means that when we want to mark a -// Var_expression as having lvalue semantics, we need to make a copy -// of it. Example: -// -// mystruct.myfield += 42 -// -// When this is lowered to eliminate the += operator, we get a tree -// -// mystruct.myfield = mystruct.field + 42 -// -// in which the "mystruct" same Var_expression is referenced on both -// LHS and RHS subtrees. This in turn means that if we try to mark the -// LHS Var_expression the RHS Var_expression will also be marked. To -// address this issue, the code below clones any var_expression before -// applying an lvalue marking. -// - -class Mark_lvalue_varexprs : public Traverse -{ - public: - Mark_lvalue_varexprs() - : Traverse(traverse_expressions) - { } - - protected: - int - expression(Expression**); - - private: -}; - -int Mark_lvalue_varexprs::expression(Expression** ppexpr) -{ - Expression* e = *ppexpr; - - Var_expression* ve = e->var_expression(); - if (ve) - { - ve = new Var_expression(ve->named_object(), ve->location()); - ve->set_in_lvalue_pos(); - *ppexpr = ve; - return TRAVERSE_EXIT; - } - - Field_reference_expression* fre = e->field_reference_expression(); - if (fre != NULL) - return TRAVERSE_CONTINUE; - - Array_index_expression* aie = e->array_index_expression(); - if (aie != NULL) - { - Mark_lvalue_varexprs mlve; - aie->set_is_lvalue(); - aie->array()->traverse_subexpressions(&mlve); - return TRAVERSE_EXIT; - } - - Unary_expression* ue = e->unary_expression(); - if (ue && ue->op() == OPERATOR_MULT) - return TRAVERSE_CONTINUE; - - Type_conversion_expression* ce = e->conversion_expression(); - if (ce) - return TRAVERSE_CONTINUE; - - Temporary_reference_expression* tre = - e->temporary_reference_expression(); - if (tre) - { - tre = new Temporary_reference_expression(tre->statement(), - tre->location()); - *ppexpr = tre; - tre->set_is_lvalue(); - return TRAVERSE_EXIT; - } - - return TRAVERSE_EXIT; -} - // Convert an assignment statement to the backend representation. Bstatement* @@ -942,9 +848,6 @@ Assignment_statement::do_get_backend(Tra return context->backend()->expression_statement(bfunction, rhs); } - Mark_lvalue_varexprs mlve; - Expression::traverse(&this->lhs_, &mlve); - Bexpression* lhs = this->lhs_->get_backend(context); Expression* conv = Expression::convert_for_assignment(context->gogo(), this->lhs_->type(), Index: gcc/go/gofrontend/types.cc =================================================================== --- gcc/go/gofrontend/types.cc (revision 254090) +++ gcc/go/gofrontend/types.cc (working copy) @@ -1206,8 +1206,7 @@ Type::type_descriptor_pointer(Gogo* gogo go_assert(t->type_descriptor_var_ != NULL); } Bexpression* var_expr = - gogo->backend()->var_expression(t->type_descriptor_var_, - VE_rvalue, location); + gogo->backend()->var_expression(t->type_descriptor_var_, location); Bexpression* var_addr = gogo->backend()->address_expression(var_expr, location); Type* td_type = Type::make_type_descriptor_type(); @@ -2385,7 +2384,7 @@ Type::gc_symbol_pointer(Gogo* gogo) } Location bloc = Linemap::predeclared_location(); Bexpression* var_expr = - gogo->backend()->var_expression(t->gc_symbol_var_, VE_rvalue, bloc); + gogo->backend()->var_expression(t->gc_symbol_var_, bloc); Bexpression* addr_expr = gogo->backend()->address_expression(var_expr, bloc); @@ -7395,7 +7394,6 @@ Array_type::get_value_pointer(Gogo*, Exp else if (ve != NULL) { ve = new Var_expression(ve->named_object(), ve->location()); - ve->set_in_lvalue_pos(); array = ve; } } Index: gcc/go/gofrontend/wb.cc =================================================================== --- gcc/go/gofrontend/wb.cc (revision 254090) +++ gcc/go/gofrontend/wb.cc (working copy) @@ -175,7 +175,6 @@ Write_barriers::variable(Named_object* n // Replace the initializer. Location loc = init->location(); Expression* ref = Expression::make_var_reference(no, loc); - ref->var_expression()->set_in_lvalue_pos(); Statement_inserter inserter(this->gogo_, var); Statement* s = this->gogo_->assign_with_write_barrier(NULL, NULL, &inserter,