diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-09-05 14:31:00 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-09-05 14:31:00 -0400 |
commit | 37977343ff4f9dcb047d966d8cbaa222964763f9 (patch) | |
tree | aacb3a3af08fa566f09f425f0900b3b9f5d5ccdd /gcc | |
parent | c880fca6cdb16c5efe3a12ee7ecdb2435f5e7105 (diff) | |
download | gcc-37977343ff4f9dcb047d966d8cbaa222964763f9.zip gcc-37977343ff4f9dcb047d966d8cbaa222964763f9.tar.gz gcc-37977343ff4f9dcb047d966d8cbaa222964763f9.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/name-lookup.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C | 1 |
3 files changed, 6 insertions, 0 deletions
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index cd3947c..bfe17b7 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 37a183d..7dbe7e1 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 68388a6..bc0e7a5 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{}; } |