On Tue, Jan 19, 2021 at 05:38:20PM -0500, Marek Polacek via Gcc-patches 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.
> 
> > > 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?

The latter seems to be true, therefore a new patch is attached.
  
> > 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.

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

-- >8 --
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)

This is now tracked in PR98756.

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/ChangeLog:

        PR c++/98545
        * doc/invoke.texi: Update C++ ABI Version 15 description.

gcc/testsuite/ChangeLog:

        PR c++/98545
        * g++.dg/abi/mangle76.C: New test.
---
 gcc/cp/mangle.c                     |  7 ++++-
 gcc/doc/invoke.texi                 |  3 ++-
 gcc/testsuite/g++.dg/abi/mangle76.C | 40 +++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/abi/mangle76.C

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 11eb8962d28..9b358bbc5a1 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3349,7 +3349,12 @@ write_expression (tree expr)
   else if (dependent_name (expr))
     {
       tree name = dependent_name (expr);
-      gcc_assert (!IDENTIFIER_ANY_OP_P (name));
+      if (abi_version_at_least (15) && IDENTIFIER_ANY_OP_P (name))
+       {
+         write_string ("on");
+         if (abi_warn_or_compat_version_crosses (15))
+           G.need_abi_warning = 1;
+       }
       write_unqualified_id (name);
     }
   else
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5f4a06625eb..99d25462e48 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2837,7 +2837,8 @@ Version 14, which first appeared in G++ 10, corrects the 
mangling of
 the nullptr expression.
 
 Version 15, which first appeared in G++ 11, changes the mangling of
-@code{__alignof__} to be distinct from that of @code{alignof}.
+@code{__alignof__} to be distinct from that of @code{alignof}, and
+dependent operator names.
 
 See also @option{-Wabi}.
 
diff --git a/gcc/testsuite/g++.dg/abi/mangle76.C 
b/gcc/testsuite/g++.dg/abi/mangle76.C
new file mode 100644
index 00000000000..fe326e6c689
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle76.C
@@ -0,0 +1,40 @@
+// PR c++/98545
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wabi=14" }
+
+class a {
+public:
+  a();
+  template <typename b> a(b);
+};
+template <class = double> using c = a;
+class f {
+protected:
+  template <class d, class e> void operator()(d, double, e);
+};
+class i : f {
+public:
+  template <class... g>
+  [[gnu::used]] auto h(g...) -> decltype(operator()(g()...)) {} // { 
dg-warning "mangled name" }
+// { dg-final { scan-assembler 
"_ZN1i1hIJ1adS1_EEEDTcldtdefpTonclspcvT__EEEDpS2_" } }
+};
+template <class> class C {
+public:
+  template <class j> C(j);
+  i k() const;
+  int operator()() {
+    int l = 10;
+    c<> m, n;
+    operator()(m, l, n);
+    return 0;
+  }
+  int operator()(c<> &, c<> const &, c<> const &) const;
+  template <class d, class e> void k(d m, double gamma, e o) const {
+    k().h(m, gamma, o);
+  }
+};
+template <class r> int C<r>::operator()(c<> &, c<> const &, c<> const &) const 
{
+  [&](c<> m, double gamma, c<> o) { k(m, gamma, o); };
+  return 0;
+}
+c<> p = C<double>(p)();

base-commit: 0fb7aa205afebe178c06683037ccd4c41104337a
-- 
2.29.2

Reply via email to