[Bug c++/77489] Invalid mangling of static local variables
trippels at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Sep 5 16:07:00 GMT 2016
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77489
--- Comment #2 from Markus Trippelsdorf <trippels at gcc dot gnu.org> ---
Untested patch:
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index bd23260c0883..322f52944f41 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1896,7 +1896,8 @@ discriminator_for_string_literal (tree /*function*/,
return 0;
}
-/* <discriminator> := _ <number>
+/* <discriminator> := _ <number> # when number < 10
+ := __ <number> _ # when number >= 10
The discriminator is used only for the second and later occurrences
of the same name within a single function. In this case <number> is
@@ -1909,7 +1910,11 @@ write_discriminator (const int discriminator)
if (discriminator > 0)
{
write_char ('_');
+ if (discriminator - 1 >= 10)
+ write_char ('_');
write_unsigned_number (discriminator - 1);
+ if (discriminator - 1 >= 10)
+ write_char ('_');
}
}
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 1c2bce291797..47099c1d0391 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -3529,7 +3529,11 @@ d_local_name (struct d_info *di)
}
}
-/* <discriminator> ::= _ <(non-negative) number>
+/* <discriminator> ::= _ <number> # when number < 10
+ ::= __ <number> _ # when number >= 10
+
+ <discriminator> ::= _ <number> # when number >=10
+ is also accepted to support gcc versions that wrongly mangled that way.
We demangle the discriminator, but we don't print it out. FIXME:
We should print it out in verbose mode. */
@@ -3537,14 +3541,24 @@ d_local_name (struct d_info *di)
static int
d_discriminator (struct d_info *di)
{
- int discrim;
+ int discrim, num_underscores = 1;
if (d_peek_char (di) != '_')
return 1;
d_advance (di, 1);
+ if (d_peek_char (di) == '_') {
+ ++num_underscores;
+ d_advance (di, 1);
+ }
discrim = d_number (di);
if (discrim < 0)
return 0;
+ if ((num_underscores > 1) && discrim >= 10) {
+ if (d_peek_char (di) == '_')
+ d_advance (di, 1);
+ else
+ return 0;
+ }
return 1;
}
More information about the Gcc-bugs
mailing list