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

Reply via email to