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

Reply via email to