This patch to the Go frontend includes the type in the export data when an inlinable function refers to a string or bool constant. The patch consolidates the identical code for constant type export into a pair of static methods. This fixes https://golang.org/issue/35739. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
727a2e1c4ad1c3978a08423b1c020dc213154df0 diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 45a7b422a29..ce96537e346 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -b73a8f17dfe8d7c7ecc9ccd0317be5abe71c5509 +94808b9af5cd9b9102ae9680a0e5f124c6793815 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/expressions.cc b/gcc/go/gofrontend/expressions.cc index 0350e51d3a6..e76bc6997c1 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1823,6 +1823,31 @@ Expression::make_unknown_reference(Named_object* no, Location location) return new Unknown_expression(no, location); } +// Start exporting a type conversion for a constant, if needed. This +// returns whether we need to export a closing parenthesis. + +bool +Expression::export_constant_type(Export_function_body* efb, Type* type) +{ + if (type == NULL + || type->is_abstract() + || type == efb->type_context()) + return false; + efb->write_c_string("$convert("); + efb->write_type(type); + efb->write_c_string(", "); + return true; +} + +// Finish a type conversion for a constant. + +void +Expression::finish_export_constant_type(Export_function_body* efb, bool needed) +{ + if (needed) + efb->write_c_string(")"); +} + // A boolean expression. class Boolean_expression : public Expression @@ -1878,8 +1903,7 @@ class Boolean_expression : public Expression { return 1; } void - do_export(Export_function_body* efb) const - { efb->write_c_string(this->val_ ? "$true" : "$false"); } + do_export(Export_function_body* efb) const; void do_dump_expression(Ast_dump_context* ast_dump_context) const @@ -1926,6 +1950,16 @@ Boolean_expression::do_determine_type(const Type_context* context) this->type_ = Type::lookup_bool_type(); } +// Export a boolean constant. + +void +Boolean_expression::do_export(Export_function_body* efb) const +{ + bool exported_type = Expression::export_constant_type(efb, this->type_); + efb->write_c_string(this->val_ ? "$true" : "$false"); + Expression::finish_export_constant_type(efb, exported_type); +} + // Import a boolean constant. Expression* @@ -2055,7 +2089,9 @@ String_expression::export_string(String_dump* exp, void String_expression::do_export(Export_function_body* efb) const { + bool exported_type = Expression::export_constant_type(efb, this->type_); String_expression::export_string(efb, this); + Expression::finish_export_constant_type(efb, exported_type); } // Import a string expression. @@ -2547,16 +2583,7 @@ Integer_expression::export_integer(String_dump* exp, const mpz_t val) void Integer_expression::do_export(Export_function_body* efb) const { - bool added_type = false; - if (this->type_ != NULL - && !this->type_->is_abstract() - && this->type_ != efb->type_context()) - { - efb->write_c_string("$convert("); - efb->write_type(this->type_); - efb->write_c_string(", "); - added_type = true; - } + bool exported_type = Expression::export_constant_type(efb, this->type_); Integer_expression::export_integer(efb, this->val_); if (this->is_character_constant_) @@ -2564,8 +2591,7 @@ Integer_expression::do_export(Export_function_body* efb) const // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); - if (added_type) - efb->write_c_string(")"); + Expression::finish_export_constant_type(efb, exported_type); } // Import an integer, floating point, or complex value. This handles @@ -2953,23 +2979,13 @@ Float_expression::export_float(String_dump *exp, const mpfr_t val) void Float_expression::do_export(Export_function_body* efb) const { - bool added_type = false; - if (this->type_ != NULL - && !this->type_->is_abstract() - && this->type_ != efb->type_context()) - { - efb->write_c_string("$convert("); - efb->write_type(this->type_); - efb->write_c_string(", "); - added_type = true; - } + bool exported_type = Expression::export_constant_type(efb, this->type_); Float_expression::export_float(efb, this->val_); // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); - if (added_type) - efb->write_c_string(")"); + Expression::finish_export_constant_type(efb, exported_type); } // Dump a floating point number to the dump file. @@ -3184,23 +3200,13 @@ Complex_expression::export_complex(String_dump* exp, const mpc_t val) void Complex_expression::do_export(Export_function_body* efb) const { - bool added_type = false; - if (this->type_ != NULL - && !this->type_->is_abstract() - && this->type_ != efb->type_context()) - { - efb->write_c_string("$convert("); - efb->write_type(this->type_); - efb->write_c_string(", "); - added_type = true; - } + bool exported_type = Expression::export_constant_type(efb, this->type_); Complex_expression::export_complex(efb, this->val_); // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); - if (added_type) - efb->write_c_string(")"); + Expression::finish_export_constant_type(efb, exported_type); } // Dump a complex expression to the dump file. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index acb2732bdde..d2975238572 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -1237,6 +1237,14 @@ class Expression virtual void do_dump_expression(Ast_dump_context*) const = 0; + // Start exporting a type conversion for a constant, if needed. + static bool + export_constant_type(Export_function_body*, Type*); + + // Finish exporting a type conversion for a constant. + static void + finish_export_constant_type(Export_function_body*, bool); + // Varargs lowering creates a slice object (unnamed compiler temp) // to contain the variable length collection of values. The enum // below tells the lowering routine whether it can mark that temp