https://gcc.gnu.org/g:a030fcad4f9f490a08db0a4cad4c22635a0585c1

commit r15-3797-ga030fcad4f9f490a08db0a4cad4c22635a0585c1
Author: Simon Martin <si...@nasilyan.com>
Date:   Mon Sep 16 13:45:32 2024 +0200

    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.

Diff:
---
 gcc/cp/mangle.cc                             |  8 +++++++-
 gcc/testsuite/g++.dg/cpp0x/decltype83.C      | 20 ++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/decltype83a.C     | 18 ++++++++++++++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-ice3.C     | 19 +++++++++++++++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-ice3a.C    | 17 +++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/nontype-class67.C |  9 +++++++++
 6 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index 46dc6923adde..17988d69e1ea 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 000000000000..b71a302d5ebb
--- /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 000000000000..27c363651f13
--- /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 000000000000..b6a2056724fd
--- /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 000000000000..6394e6c4914f
--- /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 000000000000..accf42848835
--- /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}>();

Reply via email to