aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-08-17 21:06:39 +0200
committerJakub Jelinek <jakub@redhat.com>2021-08-17 21:18:29 +0200
commit32c3a75390623a0470df52af13f78baddd562981 (patch)
tree355341d9af7a9a5254daaebedabba684d33c457e /gcc/cp/decl.c
parent798666392b512a585f0de2983a5d3423e960959e (diff)
downloadgcc-32c3a75390623a0470df52af13f78baddd562981.zip
gcc-32c3a75390623a0470df52af13f78baddd562981.tar.gz
gcc-32c3a75390623a0470df52af13f78baddd562981.tar.bz2
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.
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b3671ee..32d07ba 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4470,6 +4470,13 @@ cxx_init_decl_processing (void)
tree bool_vaftype = build_varargs_function_type_list (boolean_type_node,
NULL_TREE);
decl
+ = add_builtin_function ("__builtin_is_corresponding_member",
+ bool_vaftype,
+ CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
+ BUILT_IN_FRONTEND, NULL, NULL_TREE);
+ set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+
+ decl
= add_builtin_function ("__builtin_is_pointer_interconvertible_with_class",
bool_vaftype,
CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,