Skip to content
Snippets Groups Projects
Commit 32c3a753 authored by Jakub Jelinek's avatar Jakub Jelinek
Browse files

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.
parent 79866639
No related branches found
No related tags found
Loading
Showing
with 879 additions and 31 deletions
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment