diff mbox series

c++: local class memfn synth from noexcept context [PR113063]

Message ID 20240820155239.2844549-1-ppalka@redhat.com
State New
Headers show
Series c++: local class memfn synth from noexcept context [PR113063] | expand

Commit Message

Patrick Palka Aug. 20, 2024, 3:52 p.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk only?

-- >8 --

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 local class case.

	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.
---
 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(+)

Comments

Jason Merrill Aug. 26, 2024, 7:25 p.m. UTC | #1
On 8/20/24 11:52 AM, Patrick Palka wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> OK for trunk only?

OK.

> -- >8 --
> 
> 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 local class case.
> 
> 	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.
> ---
>   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 70ad4cbf3b5..6fb664b0082 100644
> --- a/gcc/cp/name-lookup.cc
> +++ b/gcc/cp/name-lookup.cc
> @@ -8775,6 +8775,7 @@ struct local_state_t
>   {
>     int cp_unevaluated_operand;
>     int c_inhibit_evaluation_warnings;
> +  int saved_cp_noexcept_operand;
>   
>     static local_state_t
>     save_and_clear ()
> @@ -8784,6 +8785,8 @@ struct local_state_t
>       ::cp_unevaluated_operand = 0;
>       s.c_inhibit_evaluation_warnings = ::c_inhibit_evaluation_warnings;
>       ::c_inhibit_evaluation_warnings = 0;
> +    s.saved_cp_noexcept_operand = cp_noexcept_operand;
> +    cp_noexcept_operand = 0;
>       return s;
>     }
>   
> @@ -8792,6 +8795,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->saved_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{};
>   }
diff mbox series

Patch

diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 70ad4cbf3b5..6fb664b0082 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -8775,6 +8775,7 @@  struct local_state_t
 {
   int cp_unevaluated_operand;
   int c_inhibit_evaluation_warnings;
+  int saved_cp_noexcept_operand;
 
   static local_state_t
   save_and_clear ()
@@ -8784,6 +8785,8 @@  struct local_state_t
     ::cp_unevaluated_operand = 0;
     s.c_inhibit_evaluation_warnings = ::c_inhibit_evaluation_warnings;
     ::c_inhibit_evaluation_warnings = 0;
+    s.saved_cp_noexcept_operand = cp_noexcept_operand;
+    cp_noexcept_operand = 0;
     return s;
   }
 
@@ -8792,6 +8795,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->saved_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{};
 }