https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98712
--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jason Merrill <ja...@gcc.gnu.org>: https://gcc.gnu.org/g:09d886e671f2230acca082e6579a69b8df8fb202 commit r12-4202-g09d886e671f2230acca082e6579a69b8df8fb202 Author: Jakub Jelinek <ja...@redhat.com> Date: Fri Oct 1 17:07:17 2021 +0200 c++: defaulted <=> with bitfields [PR102490] The testcases in the patch are either miscompiled or ICE with checking, because the defaulted operator== is synthesized too early (but only if constexpr), when the corresponding class type is still incomplete type. The problem is that at that point the bitfield FIELD_DECLs still have as TREE_TYPE their underlying type rather than integral type with their precision and when layout_class_type is called for the class soon after that, it changes those types but the COMPONENT_REFs type stay the way that they were during the operator== synthesize_method type and the middle-end is then upset by the mismatch of types. As what exact type will be given isn't just a one liner but quite long code especially for over-sized bitfields, I think it is best to just not synthesize the comparison operators so early and call defaulted_late_check for them once again as soon as the class is complete. This is also a problem for virtual operator<=>, where we need to compare the noexcept-specifier to validate the override before the class is complete. Rather than try to defer that comparison, maybe_instantiate_noexcept now calls maybe_synthesize_method, which calls build_comparison_op in non-defining mode if the class isn't complete yet. In that situation we also might not have base fields yet, so we look in the binfo for the bases. Co-authored-by: Jason Merrill <ja...@redhat.com> 2021-10-01 Jakub Jelinek <ja...@redhat.com> PR c++/98712 PR c++/102490 * cp-tree.h (maybe_synthesize_method): Declare. * method.c (genericize_spaceship): Use LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED instead of LOOKUP_NORMAL for flags. (comp_info): Remove defining member. Add complain, code, retcat. (comp_info::comp_info): Adjust. (do_one_comp): Split out from build_comparison_op. Use LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED instead of LOOKUP_NORMAL for flags. (build_comparison_op): Add defining argument. Adjust comp_info construction. Use defining instead of info.defining. Assert that if defining, ctype is a complete type. Walk base binfos. (synthesize_method, maybe_explain_implicit_delete, explain_implicit_non_constexpr): Adjust build_comparison_op callers. (maybe_synthesize_method): New function. * class.c (check_bases_and_members): Don't call defaulted_late_check for sfk_comparison. (finish_struct_1): Call it here instead after class has been completed. * pt.c (maybe_instantiate_noexcept): Call maybe_synthesize_method instead of synthesize_method. * g++.dg/cpp2a/spaceship-synth8.C (std::strong_ordering): Provide more complete definition. (std::strong_ordering::less, std::strong_ordering::equal, std::strong_ordering::greater): Define. * g++.dg/cpp2a/spaceship-synth12.C: New test. * g++.dg/cpp2a/spaceship-synth13.C: New test. * g++.dg/cpp2a/spaceship-synth14.C: New test. * g++.dg/cpp2a/spaceship-eq11.C: New test. * g++.dg/cpp2a/spaceship-eq12.C: New test. * g++.dg/cpp2a/spaceship-eq13.C: New test.