diff options
author | Marek Polacek <polacek@redhat.com> | 2021-01-13 16:33:39 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2021-01-22 13:02:23 -0500 |
commit | 25fc4d01a8ed1888e6a65597a3387349eb3c950c (patch) | |
tree | 99ba82b9c52ec22db47720056a90198e905c81b7 /gcc | |
parent | bf8ee9e4eed6ba1a6d77b4cf168df480e1f954da (diff) | |
download | gcc-25fc4d01a8ed1888e6a65597a3387349eb3c950c.zip gcc-25fc4d01a8ed1888e6a65597a3387349eb3c950c.tar.gz gcc-25fc4d01a8ed1888e6a65597a3387349eb3c950c.tar.bz2 |
c++: ICE when mangling operator name [PR98545]
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/mangle.c | 13 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle76.C | 40 |
3 files changed, 52 insertions, 4 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 11eb896..0a9e5aa 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 5f4a066..99d2546 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 0000000..fe326e6 --- /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)(); |