diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-10-01 17:07:17 +0200 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-10-05 22:41:00 -0400 |
commit | 09d886e671f2230acca082e6579a69b8df8fb202 (patch) | |
tree | 47c7586af3681fc0b819c9b8ebf804d73d340ed2 /gcc/fortran/resolve.c | |
parent | bb6194e0b44a8262d8de304be3bd3ee65187772a (diff) | |
download | gcc-09d886e671f2230acca082e6579a69b8df8fb202.zip gcc-09d886e671f2230acca082e6579a69b8df8fb202.tar.gz gcc-09d886e671f2230acca082e6579a69b8df8fb202.tar.bz2 |
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.
Diffstat (limited to 'gcc/fortran/resolve.c')
0 files changed, 0 insertions, 0 deletions