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 <jason@redhat.com>
This commit is contained in:
Patrick Palka 2024-09-05 14:31:00 -04:00
parent c880fca6cd
commit 37977343ff
3 changed files with 6 additions and 0 deletions

View file

@ -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_;
}
};

View file

@ -10,4 +10,5 @@ int main() {
X x;
static_assert(noexcept(x <=> x));
x <=> x;
constexpr auto r = x <=> x;
}

View file

@ -13,4 +13,5 @@ int main() {
X x;
static_assert(noexcept(x <=> x));
x <=> x;
constexpr auto r = X{} <=> X{};
}