]> gcc.gnu.org Git - gcc.git/commit
c++: Implement P0466R5 __cpp_lib_is_layout_compatible compiler helpers [PR101539]
authorJakub Jelinek <jakub@redhat.com>
Tue, 17 Aug 2021 19:06:39 +0000 (21:06 +0200)
committerJakub Jelinek <jakub@redhat.com>
Tue, 17 Aug 2021 19:18:29 +0000 (21:18 +0200)
commit32c3a75390623a0470df52af13f78baddd562981
tree355341d9af7a9a5254daaebedabba684d33c457e
parent798666392b512a585f0de2983a5d3423e960959e
c++: Implement P0466R5 __cpp_lib_is_layout_compatible compiler helpers [PR101539]

The following patch implements __is_layout_compatible trait and
__builtin_is_corresponding_member helper function for the
std::is_corresponding_member template function.

As the current definition of layout compatible type has various problems,
which result e.g. in corresponding members in layout compatible types having
different member offsets, the patch anticipates some changes to the C++
standard:
1) class or enumeral types aren't layout compatible if they have different
   alignment or size
2) if two members have different offsets, they can't be corresponding members
   ([[no_unique_address]] with empty types can change that, or alignas
   on the member decls)
3) in unions, bitfields can't correspond to non-unions, or bitfields can't
   correspond to bitfields with different widths, or members with
   [[no_unique_address]] can't correspond to members without that attribute

__builtin_is_corresponding_member for anonymous structs (GCC extension) will
recurse into the anonymous structs.  For anonymous unions it will emit
a sorry if it can't prove such member types can't appear in the
anonymous unions or anonymous aggregates in that union, because
corresponding member is defined only using common initial sequence which is
only defined for std-layout non-union class types and so I have no idea what
to do otherwise in that case.

2021-08-17  Jakub Jelinek  <jakub@redhat.com>

PR c++/101539
gcc/c-family/
* c-common.h (enum rid): Add RID_IS_LAYOUT_COMPATIBLE.
* c-common.c (c_common_reswords): Add __is_layout_compatible.
gcc/cp/
* cp-tree.h (enum cp_trait_kind): Add CPTK_IS_LAYOUT_COMPATIBLE.
(enum cp_built_in_function): Add CP_BUILT_IN_IS_CORRESPONDING_MEMBER.
(fold_builtin_is_corresponding_member, next_common_initial_seqence,
layout_compatible_type_p): Declare.
* parser.c (cp_parser_primary_expression): Handle
RID_IS_LAYOUT_COMPATIBLE.
(cp_parser_trait_expr): Likewise.
* cp-objcp-common.c (names_builtin_p): Likewise.
* constraint.cc (diagnose_trait_expr): Handle
CPTK_IS_LAYOUT_COMPATIBLE.
* decl.c (cxx_init_decl_processing): Register
__builtin_is_corresponding_member builtin.
* constexpr.c (cxx_eval_builtin_function_call): Handle
CP_BUILT_IN_IS_CORRESPONDING_MEMBER builtin.
* semantics.c (is_corresponding_member_union,
is_corresponding_member_aggr, fold_builtin_is_corresponding_member):
New functions.
(trait_expr_value): Handle CPTK_IS_LAYOUT_COMPATIBLE.
(finish_trait_expr): Likewise.
* typeck.c (next_common_initial_seqence, layout_compatible_type_p):
New functions.
* cp-gimplify.c (cp_gimplify_expr): Fold
CP_BUILT_IN_IS_CORRESPONDING_MEMBER.
(cp_fold): Likewise.
* tree.c (builtin_valid_in_constant_expr_p): Handle
CP_BUILT_IN_IS_CORRESPONDING_MEMBER.
* cxx-pretty-print.c (pp_cxx_trait_expression): Handle
CPTK_IS_LAYOUT_COMPATIBLE.
* class.c (remove_zero_width_bit_fields): Remove.
(layout_class_type): Don't call it.
gcc/testsuite/
* g++.dg/cpp2a/is-corresponding-member1.C: New test.
* g++.dg/cpp2a/is-corresponding-member2.C: New test.
* g++.dg/cpp2a/is-corresponding-member3.C: New test.
* g++.dg/cpp2a/is-corresponding-member4.C: New test.
* g++.dg/cpp2a/is-corresponding-member5.C: New test.
* g++.dg/cpp2a/is-corresponding-member6.C: New test.
* g++.dg/cpp2a/is-corresponding-member7.C: New test.
* g++.dg/cpp2a/is-corresponding-member8.C: New test.
* g++.dg/cpp2a/is-layout-compatible1.C: New test.
* g++.dg/cpp2a/is-layout-compatible2.C: New test.
* g++.dg/cpp2a/is-layout-compatible3.C: New test.
25 files changed:
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/cp/class.c
gcc/cp/constexpr.c
gcc/cp/constraint.cc
gcc/cp/cp-gimplify.c
gcc/cp/cp-objcp-common.c
gcc/cp/cp-tree.h
gcc/cp/cxx-pretty-print.c
gcc/cp/decl.c
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-corresponding-member8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-layout-compatible1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-layout-compatible2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/is-layout-compatible3.C [new file with mode: 0644]
This page took 0.065908 seconds and 6 git commands to generate.