* Go patch committed: Fix inlining method with empty param/receiver
@ 2019-04-25 6:49 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2019-04-25 6:49 UTC (permalink / raw)
To: gcc-patches, gofrontend-dev
[-- Attachment #1: Type: text/plain, Size: 648 bytes --]
This patch to the Go frontend by Than McIntosh fixes a problem with
Function_declaration::import_function relating to how no-name or
"sink" parameters are handled. In Gogo::start_function (for the
non-inline case) when parameter bindings are being added, parameters
with empty/sink names are renamed to synthesized "r.%d" / "p.%d" names
so as to avoid collisions. This same handling needs to be present
when creating the bindings for an inline function that's being
instantiated after being read from export data. This fixes
https://golang.org/issue/31637. Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu. Committed to mainline.
Ian
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 5306 bytes --]
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE (revision 270552)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-56fe6a00892252edb4b28f8660ce29a985c48702
+cb6fb7285bac72389bdce7ecfe87f9366022571a
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc (revision 270552)
+++ gcc/go/gofrontend/gogo.cc (working copy)
@@ -1832,21 +1832,18 @@ Gogo::start_function(const std::string&
Variable* this_param = new Variable(receiver->type(), NULL, false,
true, true, location);
std::string rname = receiver->name();
- if (rname.empty() || Gogo::is_sink_name(rname))
- {
- // We need to give receivers a name since they wind up in
- // DECL_ARGUMENTS. FIXME.
- static unsigned int count;
- char buf[50];
- snprintf(buf, sizeof buf, "r.%u", count);
- ++count;
- rname = buf;
- }
+ unsigned rcounter = 0;
+
+ // We need to give a nameless receiver parameter a synthesized name to
+ // avoid having it clash with some other nameless param. FIXME.
+ Gogo::rename_if_empty(&rname, "r", &rcounter);
+
block->bindings()->add_variable(rname, NULL, this_param);
}
const Typed_identifier_list* parameters = type->parameters();
bool is_varargs = type->is_varargs();
+ unsigned pcounter = 0;
if (parameters != NULL)
{
for (Typed_identifier_list::const_iterator p = parameters->begin();
@@ -1859,16 +1856,11 @@ Gogo::start_function(const std::string&
param->set_is_varargs_parameter();
std::string pname = p->name();
- if (pname.empty() || Gogo::is_sink_name(pname))
- {
- // We need to give parameters a name since they wind up
- // in DECL_ARGUMENTS. FIXME.
- static unsigned int count;
- char buf[50];
- snprintf(buf, sizeof buf, "p.%u", count);
- ++count;
- pname = buf;
- }
+
+ // We need to give each nameless parameter a non-empty name to avoid
+ // having it clash with some other nameless param. FIXME.
+ Gogo::rename_if_empty(&pname, "p", &pcounter);
+
block->bindings()->add_variable(pname, NULL, param);
}
}
@@ -2313,6 +2305,20 @@ Gogo::add_variable(const std::string& na
return no;
}
+void
+Gogo::rename_if_empty(std::string* pname, const char* tag, unsigned* count)
+{
+ if (pname->empty() || Gogo::is_sink_name(*pname))
+ {
+ char buf[50];
+ go_assert(strlen(tag) < 10);
+ snprintf(buf, sizeof buf, "%s.%u", tag, *count);
+ ++(*count);
+ *pname = buf;
+ }
+}
+
+
// Add a sink--a reference to the blank identifier _.
Named_object*
@@ -6904,11 +6910,20 @@ Function_declaration::import_function_bo
const Typed_identifier* receiver = fntype->receiver();
Variable* recv_param = new Variable(receiver->type(), NULL, false,
true, true, start_loc);
- outer->bindings()->add_variable(receiver->name(), NULL, recv_param);
+
+ std::string rname = receiver->name();
+ unsigned rcounter = 0;
+
+ // We need to give a nameless receiver a name to avoid having it
+ // clash with some other nameless param. FIXME.
+ Gogo::rename_if_empty(&rname, "r", &rcounter);
+
+ outer->bindings()->add_variable(rname, NULL, recv_param);
}
const Typed_identifier_list* params = fntype->parameters();
bool is_varargs = fntype->is_varargs();
+ unsigned pcounter = 0;
if (params != NULL)
{
for (Typed_identifier_list::const_iterator p = params->begin();
@@ -6919,7 +6934,14 @@ Function_declaration::import_function_bo
start_loc);
if (is_varargs && p + 1 == params->end())
param->set_is_varargs_parameter();
- outer->bindings()->add_variable(p->name(), NULL, param);
+
+ std::string pname = p->name();
+
+ // We need to give each nameless parameter a non-empty name to avoid
+ // having it clash with some other nameless param. FIXME.
+ Gogo::rename_if_empty(&pname, "p", &pcounter);
+
+ outer->bindings()->add_variable(pname, NULL, param);
}
}
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h (revision 270552)
+++ gcc/go/gofrontend/gogo.h (working copy)
@@ -220,6 +220,16 @@ class Gogo
&& name[name.length() - 2] == '.');
}
+ // Helper used when adding parameters (including receiver param) to the
+ // bindings of a function. If the specified parameter name is empty or
+ // corresponds to the sink name, param name is replaced with a new unique
+ // name. PNAME is the address of a string containing the parameter variable
+ // name to be checked/updated; TAG is a descriptive tag to be used in
+ // manufacturing the new unique name, and COUNT is the address of a counter
+ // holding the number of params renamed so far with the tag in question.
+ static void
+ rename_if_empty(std::string* pname, const char* tag, unsigned* count);
+
// Convert a pkgpath into a string suitable for a symbol
static std::string
pkgpath_for_symbol(const std::string& pkgpath);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2019-04-25 1:13 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-25 6:49 Go patch committed: Fix inlining method with empty param/receiver Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).