On 1/19/21 5:38 PM, Marek Polacek wrote:
On Tue, Jan 19, 2021 at 03:47:47PM -0500, Jason Merrill via Gcc-patches wrote:
On 1/13/21 6:39 PM, Marek Polacek wrote:
r11-6301 added some asserts in mangle.c, and now we trip over one of
them.  In particular, it's the one asserting that we didn't get
IDENTIFIER_ANY_OP_P when mangling an expression with a dependent name.

As this testcase shows, it's possible to get that, so turn the assert
into an if and write "on".  That changes the mangling in the following
way:

With this patch:

$ c++filt _ZN1i1hIJ1adS1_EEEDTcldtdefpTonclspcvT__EEEDpS2_
decltype (((*this).(operator()))((a)(), (double)(), (a)())) i::h<a, double, 
a>(a, double, a)

G++10:
$ c++filt _ZN1i1hIJ1adS1_EEEDTcldtdefpTclspcvT__EEEDpS2_
decltype (((*this).(operator()))((a)(), (double)(), (a)())) i::h<a, double, 
a>(a, double, a)

clang++/icc:
$ c++filt _ZN1i1hIJ1adS1_EEEDTclonclspcvT__EEEDpS2_
decltype ((operator())((a)(), (double)(), (a)())) i::h<a, double, a>(a, double, 
a)

I'm not sure why we differ in the "(*this)." part

Is there a PR for that?

I just opened 98756, because I didn't find any.  I can investigate where that
(*this) comes from, though it's not readily clear to me if this is a bug or not.

I think it is; in general, the mangling tries to be close to the expression as written. We're talking about adjusting that a bit to reflect the result of name lookup more, but that wouldn't make a difference to this case.

but at least the
suffix "onclspcvT__EEEDpS2_" is the same for all three compilers.  So
I hope the following fix makes sense.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

gcc/cp/ChangeLog:

        PR c++/98545
        * mangle.c (write_expression): When the expression is a dependent name
        and an operator name, write "on" before writing its name.

gcc/testsuite/ChangeLog:

        PR c++/98545
        * g++.dg/abi/mangle76.C: New test.
---
   gcc/cp/mangle.c                     |  3 ++-
   gcc/testsuite/g++.dg/abi/mangle76.C | 39 +++++++++++++++++++++++++++++
   2 files changed, 41 insertions(+), 1 deletion(-)
   create mode 100644 gcc/testsuite/g++.dg/abi/mangle76.C

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 11eb8962d28..bb3c4b76d33 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3349,7 +3349,8 @@ write_expression (tree expr)
     else if (dependent_name (expr))
       {
         tree name = dependent_name (expr);
-      gcc_assert (!IDENTIFIER_ANY_OP_P (name));
+      if (IDENTIFIER_ANY_OP_P (name))
+       write_string ("on");

Any mangling change needs to handle different -fabi-versions; see the
similar code in write_member_name.

Ah, I only looked at the unguarded IDENTIFIER_ANY_OP_P checks.  But now
I have a possibly stupid question: what version should I check?  We have
Version 11 for which the manual already says "corrects the mangling of
sizeof... expressions and *operator names*", so perhaps I could tag along
and check abi_version_at_least (11).  Or should I check Version 15 and
update the manual?

As discussed on our call today, we don't want to change the behavior of older versions, so version 15 is the answer.

And why doesn't this go through write_member_name?

We go through write_member_name:

#0  fancy_abort (file=0x2b98ef8 "/home/mpolacek/src/gcc/gcc/cp/mangle.c", 
line=3352,
     function=0x2b99751 "write_expression") at 
/home/mpolacek/src/gcc/gcc/diagnostic.c:1884
#1  0x0000000000bee91b in write_expression (expr=<overload 0x7fffea02eb20>)
     at /home/mpolacek/src/gcc/gcc/cp/mangle.c:3352
#2  0x0000000000beb3e2 in write_member_name (member=<baselink 0x7fffea043ae0>)
     at /home/mpolacek/src/gcc/gcc/cp/mangle.c:2892
#3  0x0000000000beee70 in write_expression (expr=<component_ref 0x7fffea043b40>)
     at /home/mpolacek/src/gcc/gcc/cp/mangle.c:3405
#4  0x0000000000bef1be in write_expression (expr=<call_expr 0x7fffe9ede118>)
     at /home/mpolacek/src/gcc/gcc/cp/mangle.c:3455
#5  0x0000000000be858a in write_type (type=<decltype_type 0x7fffea04b348>)
     at /home/mpolacek/src/gcc/gcc/cp/mangle.c:2343

so in write_member_name MEMBER is a BASELINK so we don't enter the
identifier_p block.

Aha.

Jason

Reply via email to