]> gcc.gnu.org Git - gcc.git/commit
c++: defaulted <=> with bitfields [PR102490]
authorJakub Jelinek <jakub@redhat.com>
Fri, 1 Oct 2021 15:07:17 +0000 (17:07 +0200)
committerJason Merrill <jason@redhat.com>
Wed, 6 Oct 2021 02:41:00 +0000 (22:41 -0400)
commit09d886e671f2230acca082e6579a69b8df8fb202
tree47c7586af3681fc0b819c9b8ebf804d73d340ed2
parentbb6194e0b44a8262d8de304be3bd3ee65187772a
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 <jason@redhat.com>
2021-10-01  Jakub Jelinek  <jakub@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.
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/method.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp2a/spaceship-eq11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/spaceship-eq12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/spaceship-eq13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/spaceship-synth12.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/spaceship-synth13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/spaceship-synth14.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/spaceship-synth8.C
This page took 0.06599 seconds and 5 git commands to generate.