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; }