Hi, While looking at more open PRs, I have discovered that the problem reported in PR109790 is very similar to that in PR100632, so I’m combining both in a single patch attached here. The fix is similar to
the one I initially submitted, only more general and I believe better. Successfully tested on x86_64-pc-linux-gnu. OK for trunk? Thanks, Simon On 10 Sep 2024, at 20:06, Simon Martin wrote: > We currently crash upon the following valid code (the case from the > PR, > invalid, can be made valid by simply adding a definition for f at line > 2) > > === cut here === > struct B { const int *p; }; > template<B> void f() {} > struct Nested { union { int k; }; } nested; > template void f<B{&nested.k}>(); > === cut here === > > The problem is that because of the anonymous union, nested.k is > represented as nested.$(decl_of_anon_union).k, and we run into an > assert > in write_member_name just before calling write_unqualified_name, > because > DECL_NAME ($decl_of_anon_union) is 0. > > This patch fixes this by relaxing the assert to also accept members > with > an ANON_AGGR_TYPE_P type, that are handled by write_unqualified_name > just fine. > > Successfully tested on x86_64-pc-linux-gnu. > > PR c++/100632 > > gcc/cp/ChangeLog: > > * mangle.cc (write_member_name): Relax assert to accept anonymous > unions. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/nontype-class67.C: New test. > > --- > gcc/cp/mangle.cc | 3 ++- > gcc/testsuite/g++.dg/cpp2a/nontype-class67.C | 9 +++++++++ > 2 files changed, 11 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class67.C > > diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc > index 46dc6923add..11dc66c8d16 100644 > --- a/gcc/cp/mangle.cc > +++ b/gcc/cp/mangle.cc > @@ -3255,7 +3255,8 @@ write_member_name (tree member) > } > else if (DECL_P (member)) > { > - gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member)); > + gcc_assert (ANON_AGGR_TYPE_P (TREE_TYPE (member)) > + || !DECL_OVERLOADED_OPERATOR_P (member)); > write_unqualified_name (member); > } > else if (TREE_CODE (member) == TEMPLATE_ID_EXPR) > 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 00000000000..accf4284883 > --- /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}>(); > -- > 2.44.0
From 3ce65d06310e694bd6a3918d87049523951c0762 Mon Sep 17 00:00:00 2001 From: Simon Martin <si...@nasilyan.com> Date: Mon, 9 Sep 2024 09:31:10 +0200 Subject: [PATCH] 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 type. The problem is that before calling write_unqualified_name, write_member_name has an assert that assumes that it has an IDENTIFIER_NODE in its hand. However it's incorrect: it has an anonymous union in PR100632, and a template in PR109790. This patch fixes this by relaxing the assert to accept members that are not identifiers, that are handled by write_unqualified_name just fine. Successfully tested on x86_64-pc-linux-gnu. PR c++/109790 PR c++/100632 gcc/cp/ChangeLog: * mangle.cc (write_member_name): Relax assert to accept members that are not identifiers. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/decltype83.C: New test. * g++.dg/cpp1y/lambda-ice3.C: New test. * g++.dg/cpp2a/nontype-class67.C: New test. --- gcc/cp/mangle.cc | 3 ++- gcc/testsuite/g++.dg/cpp0x/decltype83.C | 13 +++++++++++++ gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C | 12 ++++++++++++ gcc/testsuite/g++.dg/cpp2a/nontype-class67.C | 9 +++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/decltype83.C create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/nontype-class67.C diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 46dc6923add..a63ae9f7ac6 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -3255,7 +3255,8 @@ write_member_name (tree member) } else if (DECL_P (member)) { - gcc_assert (!DECL_OVERLOADED_OPERATOR_P (member)); + gcc_assert (!identifier_p (member) + || !DECL_OVERLOADED_OPERATOR_P (member)); 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 00000000000..db104f333aa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/decltype83.C @@ -0,0 +1,13 @@ +// PR c++/109790 +// { 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>(); +} 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 00000000000..49261aaabb7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C @@ -0,0 +1,12 @@ +// PR c++/109790 +// { 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>(); +} 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 00000000000..accf4284883 --- /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}>(); -- 2.44.0