* [PATCH] c++: ICE when mangling operator name [PR98545]
@ 2021-01-13 23:39 Marek Polacek
2021-01-19 20:47 ` Jason Merrill
0 siblings, 1 reply; 8+ messages in thread
From: Marek Polacek @ 2021-01-13 23:39 UTC (permalink / raw)
To: GCC Patches, Jason Merrill
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, 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");
write_unqualified_id (name);
}
else
diff --git a/gcc/testsuite/g++.dg/abi/mangle76.C b/gcc/testsuite/g++.dg/abi/mangle76.C
new file mode 100644
index 00000000000..0c2964cbecb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle76.C
@@ -0,0 +1,39 @@
+// PR c++/98545
+// { dg-do compile { target c++11 } }
+
+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-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: 796ead19f85372e59217c9888db688a2fe11b54f
--
2.29.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] c++: ICE when mangling operator name [PR98545]
2021-01-13 23:39 [PATCH] c++: ICE when mangling operator name [PR98545] Marek Polacek
@ 2021-01-19 20:47 ` Jason Merrill
2021-01-19 22:38 ` Marek Polacek
0 siblings, 1 reply; 8+ messages in thread
From: Jason Merrill @ 2021-01-19 20:47 UTC (permalink / raw)
To: Marek Polacek, GCC Patches
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?
> 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.
And why doesn't this go through write_member_name?
> write_unqualified_id (name);
> }
> else
> diff --git a/gcc/testsuite/g++.dg/abi/mangle76.C b/gcc/testsuite/g++.dg/abi/mangle76.C
> new file mode 100644
> index 00000000000..0c2964cbecb
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/abi/mangle76.C
> @@ -0,0 +1,39 @@
> +// PR c++/98545
> +// { dg-do compile { target c++11 } }
> +
> +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-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: 796ead19f85372e59217c9888db688a2fe11b54f
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] c++: ICE when mangling operator name [PR98545]
2021-01-19 20:47 ` Jason Merrill
@ 2021-01-19 22:38 ` Marek Polacek
2021-01-21 19:44 ` [PATCH v2] " Marek Polacek
2021-01-21 22:37 ` [PATCH] " Jason Merrill
0 siblings, 2 replies; 8+ messages in thread
From: Marek Polacek @ 2021-01-19 22:38 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
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?
> 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.
Marek
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] c++: ICE when mangling operator name [PR98545]
2021-01-19 22:38 ` Marek Polacek
@ 2021-01-21 19:44 ` Marek Polacek
2021-01-21 22:41 ` Jason Merrill
2021-01-21 22:37 ` [PATCH] " Jason Merrill
1 sibling, 1 reply; 8+ messages in thread
From: Marek Polacek @ 2021-01-21 19:44 UTC (permalink / raw)
To: Jason Merrill, GCC Patches
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] c++: ICE when mangling operator name [PR98545]
2021-01-19 22:38 ` Marek Polacek
2021-01-21 19:44 ` [PATCH v2] " Marek Polacek
@ 2021-01-21 22:37 ` Jason Merrill
1 sibling, 0 replies; 8+ messages in thread
From: Jason Merrill @ 2021-01-21 22:37 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] c++: ICE when mangling operator name [PR98545]
2021-01-21 19:44 ` [PATCH v2] " Marek Polacek
@ 2021-01-21 22:41 ` Jason Merrill
2021-01-22 17:02 ` [PATCH v3] " Marek Polacek
0 siblings, 1 reply; 8+ messages in thread
From: Jason Merrill @ 2021-01-21 22:41 UTC (permalink / raw)
To: Marek Polacek, GCC Patches
On 1/21/21 2:44 PM, Marek Polacek wrote:
> 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;
We also want the warning if the version is less than 15 and the compat
version is 15 or greater. Ah, it seems write_member_name gets this
wrong, too. The abi_warn_or_compat_version_crosses check should not be
guarded by abi_version_at_least; all the other uses I'm seeing get this
right.
> + }
> 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
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] c++: ICE when mangling operator name [PR98545]
2021-01-21 22:41 ` Jason Merrill
@ 2021-01-22 17:02 ` Marek Polacek
2021-01-22 17:58 ` Jason Merrill
0 siblings, 1 reply; 8+ messages in thread
From: Marek Polacek @ 2021-01-22 17:02 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
On Thu, Jan 21, 2021 at 05:41:06PM -0500, Jason Merrill via Gcc-patches wrote:
> On 1/21/21 2:44 PM, Marek Polacek wrote:
> > @@ -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;
>
> We also want the warning if the version is less than 15 and the compat
> version is 15 or greater. Ah, it seems write_member_name gets this wrong,
> too. The abi_warn_or_compat_version_crosses check should not be guarded by
> abi_version_at_least; all the other uses I'm seeing get this right.
Ah, makes sense. Fixed both here:
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_member_name): Emit abi_warn_or_compat_version_crosses
warnings regardless of abi_version_at_least.
(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 | 13 +++++++---
gcc/doc/invoke.texi | 3 ++-
gcc/testsuite/g++.dg/abi/mangle76.C | 40 +++++++++++++++++++++++++++++
3 files changed, 52 insertions(+), 4 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..0a9e5aa79a0 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2868,9 +2868,10 @@ write_member_name (tree member)
{
if (identifier_p (member))
{
- if (abi_version_at_least (11) && IDENTIFIER_ANY_OP_P (member))
+ if (IDENTIFIER_ANY_OP_P (member))
{
- write_string ("on");
+ if (abi_version_at_least (11))
+ write_string ("on");
if (abi_warn_or_compat_version_crosses (11))
G.need_abi_warning = 1;
}
@@ -3349,7 +3350,13 @@ 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))
+ {
+ if (abi_version_at_least (15))
+ 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: eee8ed2f22b36dfe64a9516171871476e8ede477
--
2.29.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] c++: ICE when mangling operator name [PR98545]
2021-01-22 17:02 ` [PATCH v3] " Marek Polacek
@ 2021-01-22 17:58 ` Jason Merrill
0 siblings, 0 replies; 8+ messages in thread
From: Jason Merrill @ 2021-01-22 17:58 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
On 1/22/21 12:02 PM, Marek Polacek wrote:
> On Thu, Jan 21, 2021 at 05:41:06PM -0500, Jason Merrill via Gcc-patches wrote:
>> On 1/21/21 2:44 PM, Marek Polacek wrote:
>>> @@ -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;
>>
>> We also want the warning if the version is less than 15 and the compat
>> version is 15 or greater. Ah, it seems write_member_name gets this wrong,
>> too. The abi_warn_or_compat_version_crosses check should not be guarded by
>> abi_version_at_least; all the other uses I'm seeing get this right.
>
> Ah, makes sense. Fixed both here:
>
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
OK.
> -- >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_member_name): Emit abi_warn_or_compat_version_crosses
> warnings regardless of abi_version_at_least.
> (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 | 13 +++++++---
> gcc/doc/invoke.texi | 3 ++-
> gcc/testsuite/g++.dg/abi/mangle76.C | 40 +++++++++++++++++++++++++++++
> 3 files changed, 52 insertions(+), 4 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..0a9e5aa79a0 100644
> --- a/gcc/cp/mangle.c
> +++ b/gcc/cp/mangle.c
> @@ -2868,9 +2868,10 @@ write_member_name (tree member)
> {
> if (identifier_p (member))
> {
> - if (abi_version_at_least (11) && IDENTIFIER_ANY_OP_P (member))
> + if (IDENTIFIER_ANY_OP_P (member))
> {
> - write_string ("on");
> + if (abi_version_at_least (11))
> + write_string ("on");
> if (abi_warn_or_compat_version_crosses (11))
> G.need_abi_warning = 1;
> }
> @@ -3349,7 +3350,13 @@ 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))
> + {
> + if (abi_version_at_least (15))
> + 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: eee8ed2f22b36dfe64a9516171871476e8ede477
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-01-22 17:58 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-13 23:39 [PATCH] c++: ICE when mangling operator name [PR98545] Marek Polacek
2021-01-19 20:47 ` Jason Merrill
2021-01-19 22:38 ` Marek Polacek
2021-01-21 19:44 ` [PATCH v2] " Marek Polacek
2021-01-21 22:41 ` Jason Merrill
2021-01-22 17:02 ` [PATCH v3] " Marek Polacek
2021-01-22 17:58 ` Jason Merrill
2021-01-21 22:37 ` [PATCH] " Jason Merrill
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).