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

commit r14-10675-gf1dc18250d82cd123fcf9aef0a95608e4ec63d58
Author: Marek Polacek <pola...@redhat.com>
Date:   Mon Sep 16 16:42:38 2024 -0400

    c++: crash with anon VAR_DECL [PR116676]
    
    r12-3495 added maybe_warn_about_constant_value which will crash if
    it gets a nameless VAR_DECL, which is what happens in this PR.
    
    We created this VAR_DECL in cp_parser_decomposition_declaration.
    
            PR c++/116676
    
    gcc/cp/ChangeLog:
    
            * constexpr.cc (maybe_warn_about_constant_value): Check DECL_NAME.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp1z/constexpr-116676.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>
    (cherry picked from commit dfe0d4389a3ce43179563a63046ad3e74d615a08)

Diff:
---
 gcc/cp/constexpr.cc                           |  1 +
 gcc/testsuite/g++.dg/cpp1z/constexpr-116676.C | 57 +++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 9b36f7628f36..853694d78a56 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -7225,6 +7225,7 @@ maybe_warn_about_constant_value (location_t loc, tree 
decl)
       && warn_interference_size
       && !OPTION_SET_P (param_destruct_interfere_size)
       && DECL_CONTEXT (decl) == std_node
+      && DECL_NAME (decl)
       && id_equal (DECL_NAME (decl), "hardware_destructive_interference_size")
       && (LOCATION_FILE (input_location) != main_input_filename
          || module_exporting_p ())
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-116676.C 
b/gcc/testsuite/g++.dg/cpp1z/constexpr-116676.C
new file mode 100644
index 000000000000..1cb65f10a1d1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-116676.C
@@ -0,0 +1,57 @@
+// PR c++/116676
+// { dg-do compile { target c++17 } }
+
+namespace std {
+typedef __SIZE_TYPE__ size_t;
+
+  template<typename _Tp>
+    struct remove_reference
+    { typedef _Tp type; };
+
+  template<typename _Tp>
+    struct remove_reference<_Tp&>
+    { typedef _Tp type; };
+
+  template<typename _Tp>
+    struct remove_reference<_Tp&&>
+    { typedef _Tp type; };
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&
+move(_Tp &&__t) noexcept {
+  return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);
+}
+template <typename _Tp> struct tuple_size;
+template <size_t __i, typename _Tp> struct tuple_element;
+template <typename _U1, typename _U2> class __pair_base {};
+template <typename _T1, typename _T2>
+struct pair {
+  _T1 first;
+  _T2 second;
+  template <typename _U1 = _T1, typename _U2 = _T2>
+  explicit constexpr pair(const _T1 &__a, const _T2 &__b)
+      : first(__a), second(__b) {}
+};
+template <class _Tp1, class _Tp2>
+struct tuple_size<pair<_Tp1, _Tp2>>
+{
+static constexpr size_t value = 2;
+};
+template <class _Tp1, class _Tp2>
+struct tuple_element<0, pair<_Tp1, _Tp2>> {
+  typedef _Tp1 type;
+};
+template <class _Tp1, class _Tp2>
+struct tuple_element<1, pair<_Tp1, _Tp2>> {
+  typedef _Tp2 type;
+};
+
+template <size_t _Int, class _Tp1, class _Tp2>
+constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type &
+get(pair<_Tp1, _Tp2> &&__in) noexcept {
+  return (std::move(__in).first);
+}
+int t;
+auto [a, b] = std::pair<int&, int>{t, 1};
+}
+

Reply via email to