https://gcc.gnu.org/g:37977343ff4f9dcb047d966d8cbaa222964763f9

commit r15-3491-g37977343ff4f9dcb047d966d8cbaa222964763f9
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Sep 5 14:31:00 2024 -0400

    c++: local class memfn synth from noexcept context [PR113063]
    
    Extending the PR113063 testcase to additionally constant evaluate the <=>
    expression causes us to trip over the assert in cxx_eval_call_expression
    
      /* We used to shortcut trivial constructor/op= here, but nowadays
         we can only get a trivial function here with -fno-elide-constructors.  
*/
      gcc_checking_assert (!trivial_fn_p (fun)
                           || !flag_elide_constructors
                           /* We don't elide constructors when processing
                              a noexcept-expression.  */
                           || cp_noexcept_operand);
    
    since the local class's <=> was first used and therefore synthesized in
    a noexcept context and so its definition contains unelided trivial
    constructors.
    
    This patch fixes this by clearing cp_noexcept_operand alongside
    cp_unevaluated_context in the function-local case of
    maybe_push_to_top_level.
    
            PR c++/113063
    
    gcc/cp/ChangeLog:
    
            * name-lookup.cc (local_state_t): Clear and restore
            cp_noexcept_operand as well.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/spaceship-synth16.C: Also constant evaluate
            the <=> expression.
            * g++.dg/cpp2a/spaceship-synth16a.C: Likewise.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/name-lookup.cc                           | 4 ++++
 gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C  | 1 +
 gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C | 1 +
 3 files changed, 6 insertions(+)

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index cd3947cbe4f..bfe17b7cb2f 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -8781,6 +8781,7 @@ struct local_state_t
 {
   int cp_unevaluated_operand;
   int c_inhibit_evaluation_warnings;
+  int cp_noexcept_operand_;
 
   static local_state_t
   save_and_clear ()
@@ -8790,6 +8791,8 @@ struct local_state_t
     ::cp_unevaluated_operand = 0;
     s.c_inhibit_evaluation_warnings = ::c_inhibit_evaluation_warnings;
     ::c_inhibit_evaluation_warnings = 0;
+    s.cp_noexcept_operand_ = ::cp_noexcept_operand;
+    ::cp_noexcept_operand = 0;
     return s;
   }
 
@@ -8798,6 +8801,7 @@ struct local_state_t
   {
     ::cp_unevaluated_operand = this->cp_unevaluated_operand;
     ::c_inhibit_evaluation_warnings = this->c_inhibit_evaluation_warnings;
+    ::cp_noexcept_operand = this->cp_noexcept_operand_;
   }
 };
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C 
b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C
index 37a183de0f5..7dbe7e1db75 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C
@@ -10,4 +10,5 @@ int main() {
   X x;
   static_assert(noexcept(x <=> x));
   x <=> x;
+  constexpr auto r = x <=> x;
 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C 
b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C
index 68388a680b2..bc0e7a54b7e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C
@@ -13,4 +13,5 @@ int main() {
   X x;
   static_assert(noexcept(x <=> x));
   x <=> x;
+  constexpr auto r = X{} <=> X{};
 }

Reply via email to