diff options
author | Simon Martin <simon@nasilyan.com> | 2024-09-16 13:45:32 +0200 |
---|---|---|
committer | Simon Martin <simon@nasilyan.com> | 2024-09-23 15:05:48 +0200 |
commit | a030fcad4f9f490a08db0a4cad4c22635a0585c1 (patch) | |
tree | 54bf220b752e67c228e461fbe8a8ab22f60bd441 /gcc | |
parent | d7bf5e53887a467b8c5c8439e5aae3ad4e11e62e (diff) | |
download | gcc-a030fcad4f9f490a08db0a4cad4c22635a0585c1.zip gcc-a030fcad4f9f490a08db0a4cad4c22635a0585c1.tar.gz gcc-a030fcad4f9f490a08db0a4cad4c22635a0585c1.tar.bz2 |
c++: Don't crash when mangling member with anonymous union or template type [PR100632, PR109790]
We currently crash upon mangling members that have an anonymous union or
a template operator type.
The problem is that before calling write_unqualified_name,
write_member_name asserts that it has a declaration whose DECL_NAME is
an identifier node that is not that of an operator. This is wrong:
- In PR100632, it's an anonymous union declaration, hence a 0 DECL_NAME
- In PR109790, it's a legitimate template declaration for an operator
(this was accepted up to GCC 10)
This assert was added via r11-6301, to be sure that we do write the "on"
marker for operator members.
This patch removes that assert and instead
- Lets members with an anonymous union type go through
- For operators, adds the missing "on" marker for ABI versions greater
than the highest usable with GCC 10
PR c++/109790
PR c++/100632
gcc/cp/ChangeLog:
* mangle.cc (write_member_name): Handle members whose type is an
anonymous union member. Write missing "on" marker for operators
when ABI version is at least 16.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/decltype83.C: New test.
* g++.dg/cpp0x/decltype83a.C: New test.
* g++.dg/cpp1y/lambda-ice3.C: New test.
* g++.dg/cpp1y/lambda-ice3a.C: New test.
* g++.dg/cpp2a/nontype-class67.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/mangle.cc | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype83.C | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/decltype83a.C | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-ice3a.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/nontype-class67.C | 9 |
6 files changed, 90 insertions, 1 deletions
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 46dc692..17988d69 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -3255,7 +3255,13 @@ write_member_name (tree member) } else if (DECL_P (member)) { - gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member)); + if (ANON_AGGR_TYPE_P (TREE_TYPE (member))) + ; + else if (DECL_OVERLOADED_OPERATOR_P (member)) + { + if (abi_check (16)) + write_string ("on"); + } write_unqualified_name (member); } else if (TREE_CODE (member) == TEMPLATE_ID_EXPR) diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype83.C b/gcc/testsuite/g++.dg/cpp0x/decltype83.C new file mode 100644 index 0000000..b71a302 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype83.C @@ -0,0 +1,20 @@ +// PR c++/109790 +// This used to work until GCC 10; force the usage of ABI 15 (the highest +// usable in GCC 10) and check that the mangling (actually wrong; see +// decltyp83a.C) matches that of GCC 10's default ABI version (14). + +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fabi-version=15" } + +struct A { + template<class T> void operator+(T); +}; + +template<class T> +decltype(&A::operator+<T>) f(); + +int main() { + f<int>(); +} + +// { dg-final { scan-assembler "_Z1fIiEDTadsr1AplIT_EEv" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype83a.C b/gcc/testsuite/g++.dg/cpp0x/decltype83a.C new file mode 100644 index 0000000..27c3636 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype83a.C @@ -0,0 +1,18 @@ +// PR c++/109790 +// Up to GCC 10, the mangling would be missing the "on" marker, hence be wrong. +// Check that this is fixed with the latest ABI. + +// { dg-do compile { target c++11 } } + +struct A { + template<class T> void operator+(T); +}; + +template<class T> +decltype(&A::operator+<T>) f(); + +int main() { + f<int>(); +} + +// { dg-final { scan-assembler "_Z1fIiEDTadsr1AonplIT_EEv" } } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C new file mode 100644 index 0000000..b6a2056 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C @@ -0,0 +1,19 @@ +// PR c++/109790 +// This used to work until GCC 10; force the usage of ABI 15 (the highest +// usable in GCC 10) and check that the mangling (actually wrong; see +// lambda-ice3a.C) matches that of GCC 10's default ABI version (14). + +// { dg-do compile { target c++14 } } +// { dg-additional-options "-fabi-version=15" } + +auto ll = [](auto ... ){}; +template <class _Impl, class _Args> + void mm(void (_Impl::*__p)(_Args) const); +template <class _Ts> +using __impl_for = decltype(mm(&decltype(ll)::operator()<_Ts>)); +template <class _Ts> __impl_for<_Ts> f() { } +void aaa() { + f<int>(); +} + +// { dg-final { scan-assembler "_Z1fIiEDTcl2mmadsrN2llMUlDpT_E_EclIT_EEEv" } } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-ice3a.C b/gcc/testsuite/g++.dg/cpp1y/lambda-ice3a.C new file mode 100644 index 0000000..6394e6c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-ice3a.C @@ -0,0 +1,17 @@ +// PR c++/109790 +// Up to GCC 10, the mangling would be missing the "on" marker, hence be wrong. +// Check that this is fixed with the latest ABI. + +// { dg-do compile { target c++14 } } + +auto ll = [](auto ... ){}; +template <class _Impl, class _Args> + void mm(void (_Impl::*__p)(_Args) const); +template <class _Ts> +using __impl_for = decltype(mm(&decltype(ll)::operator()<_Ts>)); +template <class _Ts> __impl_for<_Ts> f() { } +void aaa() { + f<int>(); +} + +// { dg-final { scan-assembler "_Z1fIiEDTcl2mmadsrN2llMUlDpT_E_EonclIT_EEEv" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class67.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class67.C new file mode 100644 index 0000000..accf428 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class67.C @@ -0,0 +1,9 @@ +// PR c++/100632 +// { dg-do compile { target c++20 } } + +struct B { const int* p; }; +template<B> void f() {} + +struct Nested { union { int k; }; } nested; + +template void f<B{&nested.k}>(); |