Hi! On the following testcase we ICE, because synthesize_method is called twice on the same sfk_comparison method fndecl, the first time it works fine because start_preparsed_function in that case sets both current_function_decl and cfun, but second time it is called it only sets the former and keeps cfun NULL, so we ICE when trying to store current_function_returns_value. I think it is just wrong to call synthesize_method multiple times, and most synthesize_method callers avoid that by not calling it if DECL_INITIAL is already set, so this patch does that too.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-05-05 Jakub Jelinek <ja...@redhat.com> PR c++/94907 * method.c (defaulted_late_check): Don't call synthesize_method on constexpr sfk_comparison if it has been called on it already. * g++.dg/cpp2a/spaceship-synth8.C: New test. --- gcc/cp/method.c.jj 2020-04-29 09:00:24.525851362 +0200 +++ gcc/cp/method.c 2020-05-04 15:41:14.016544034 +0200 @@ -2939,7 +2939,7 @@ defaulted_late_check (tree fn) { /* If the function was declared constexpr, check that the definition qualifies. Otherwise we can define the function lazily. */ - if (DECL_DECLARED_CONSTEXPR_P (fn)) + if (DECL_DECLARED_CONSTEXPR_P (fn) && !DECL_INITIAL (fn)) synthesize_method (fn); return; } --- gcc/testsuite/g++.dg/cpp2a/spaceship-synth8.C.jj 2020-05-04 15:34:02.106002574 +0200 +++ gcc/testsuite/g++.dg/cpp2a/spaceship-synth8.C 2020-05-04 15:33:51.654158860 +0200 @@ -0,0 +1,12 @@ +// PR c++/94907 +// { dg-do compile { target c++2a } } + +namespace std { struct strong_ordering { }; } + +struct E; +struct D { + virtual std::strong_ordering operator<=>(const struct E&) const = 0; +}; +struct E : D { + std::strong_ordering operator<=>(const E&) const override = default; +}; Jakub