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

Here we first use and therefore synthesize the local class operator<=>
from an unevaluated context, which inadvertently affects synthesization
by preventing functions used within the definition (such as the copy
constructor of std::strong_ordering) from getting marked as odr-used.

This patch fixes this by using maybe_push_to_top_level in synthesize_method
which ensures cp_unevaluated_operand gets cleared even in the function-local
case.

	PR c++/113063

gcc/cp/ChangeLog:

	* method.cc (synthesize_method): Use maybe_push_to_top_level
	and maybe_pop_from_top_level.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/spaceship-synth16.C: New test.
This commit is contained in:
Patrick Palka 2023-12-19 16:33:55 -05:00
parent 7f26997e64
commit fced59166f
2 changed files with 15 additions and 10 deletions

View file

@ -1770,8 +1770,6 @@ decl_remember_implicit_trigger_p (tree decl)
void
synthesize_method (tree fndecl)
{
bool nested = (current_function_decl != NULL_TREE);
tree context = decl_function_context (fndecl);
bool need_body = true;
tree stmt;
location_t save_input_location = input_location;
@ -1795,10 +1793,7 @@ synthesize_method (tree fndecl)
it now. */
push_deferring_access_checks (dk_no_deferred);
if (! context)
push_to_top_level ();
else if (nested)
push_function_context ();
bool push_to_top = maybe_push_to_top_level (fndecl);
input_location = DECL_SOURCE_LOCATION (fndecl);
@ -1843,10 +1838,7 @@ synthesize_method (tree fndecl)
input_location = save_input_location;
if (! context)
pop_from_top_level ();
else if (nested)
pop_function_context ();
maybe_pop_from_top_level (push_to_top);
pop_deferring_access_checks ();

View file

@ -0,0 +1,13 @@
// PR c++/113063
// { dg-do link { target c++20 } }
#include <compare>
int main() {
struct X {
auto operator<=>(const X&) const = default;
};
X x;
static_assert(noexcept(x <=> x));
x <=> x;
}