GCC Bugzilla – Attachment 51186 Details for
Bug 101539
[C++20] Implement builtins for layout-compatibility and pointer-interconvertibility traits
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
gcc12-pr101539.patch
gcc12-pr101539.patch (text/plain), 11.78 KB, created by
Jakub Jelinek
on 2021-07-21 13:58:47 UTC
(
hide
)
Description:
gcc12-pr101539.patch
Filename:
MIME Type:
Creator:
Jakub Jelinek
Created:
2021-07-21 13:58:47 UTC
Size:
11.78 KB
patch
obsolete
>2021-07-21 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. > (layout_compatible_type_p): Declare. > * parser.c (cp_parser_primary_expression, cp_parser_trait_expr): > Handle RID_IS_LAYOUT_COMPATIBLE. > * cp-objcp-common.c (names_builtin_p): Likewise. > * constraint.cc (diagnose_trait_expr): Handle > CPTK_IS_LAYOUT_COMPATIBLE. > * typeck.c (layout_compatible_type_p): New function. > * semantics.c (trait_expr_value, finish_trait_expr): Handle > CPTK_IS_LAYOUT_COMPATIBLE. > * cxx-pretty-print.c (pp_cxx_trait_expression): Likewise. >gcc/testsuite/ > * g++.dg/cpp2a/is-layout-compatible1.C: New test. > >--- gcc/c-family/c-common.h.jj 2021-07-21 09:38:12.086463550 +0200 >+++ gcc/c-family/c-common.h 2021-07-21 14:15:36.826395598 +0200 >@@ -173,9 +173,9 @@ enum rid > RID_IS_ABSTRACT, RID_IS_AGGREGATE, > RID_IS_BASE_OF, RID_IS_CLASS, > RID_IS_EMPTY, RID_IS_ENUM, >- RID_IS_FINAL, RID_IS_LITERAL_TYPE, >- RID_IS_POD, RID_IS_POLYMORPHIC, >- RID_IS_SAME_AS, >+ RID_IS_FINAL, RID_IS_LAYOUT_COMPATIBLE, >+ RID_IS_LITERAL_TYPE, RID_IS_POD, >+ RID_IS_POLYMORPHIC, RID_IS_SAME_AS, > RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, > RID_IS_TRIVIALLY_ASSIGNABLE, RID_IS_TRIVIALLY_CONSTRUCTIBLE, > RID_IS_TRIVIALLY_COPYABLE, >--- gcc/c-family/c-common.c.jj 2021-07-21 09:38:12.079463651 +0200 >+++ gcc/c-family/c-common.c 2021-07-21 14:15:45.230278245 +0200 >@@ -420,6 +420,7 @@ const struct c_common_resword c_common_r > { "__is_empty", RID_IS_EMPTY, D_CXXONLY }, > { "__is_enum", RID_IS_ENUM, D_CXXONLY }, > { "__is_final", RID_IS_FINAL, D_CXXONLY }, >+ { "__is_layout_compatible", RID_IS_LAYOUT_COMPATIBLE, D_CXXONLY }, > { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY }, > { "__is_pod", RID_IS_POD, D_CXXONLY }, > { "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY }, >--- gcc/cp/cp-tree.h.jj 2021-07-20 10:08:09.786689199 +0200 >+++ gcc/cp/cp-tree.h 2021-07-21 15:06:46.478429413 +0200 >@@ -1365,6 +1365,7 @@ enum cp_trait_kind > CPTK_IS_EMPTY, > CPTK_IS_ENUM, > CPTK_IS_FINAL, >+ CPTK_IS_LAYOUT_COMPATIBLE, > CPTK_IS_LITERAL_TYPE, > CPTK_IS_POD, > CPTK_IS_POLYMORPHIC, >@@ -7795,6 +7796,7 @@ extern bool comp_except_specs (const_t > extern bool comptypes (tree, tree, int); > extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree); > extern bool similar_type_p (tree, tree); >+extern bool layout_compatible_type_p (tree, tree); > extern bool compparms (const_tree, const_tree); > extern int comp_cv_qualification (const_tree, const_tree); > extern int comp_cv_qualification (int, int); >--- gcc/cp/parser.c.jj 2021-07-15 10:16:12.954582150 +0200 >+++ gcc/cp/parser.c 2021-07-21 10:58:58.742451688 +0200 >@@ -5796,6 +5796,7 @@ cp_parser_primary_expression (cp_parser > case RID_IS_EMPTY: > case RID_IS_ENUM: > case RID_IS_FINAL: >+ case RID_IS_LAYOUT_COMPATIBLE: > case RID_IS_LITERAL_TYPE: > case RID_IS_POD: > case RID_IS_POLYMORPHIC: >@@ -10683,6 +10684,10 @@ cp_parser_trait_expr (cp_parser* parser, > case RID_IS_FINAL: > kind = CPTK_IS_FINAL; > break; >+ case RID_IS_LAYOUT_COMPATIBLE: >+ kind = CPTK_IS_LAYOUT_COMPATIBLE; >+ binary = true; >+ break; > case RID_IS_LITERAL_TYPE: > kind = CPTK_IS_LITERAL_TYPE; > break; >--- gcc/cp/cp-objcp-common.c.jj 2021-07-15 10:16:12.947582245 +0200 >+++ gcc/cp/cp-objcp-common.c 2021-07-21 11:00:36.372062141 +0200 >@@ -413,6 +413,7 @@ names_builtin_p (const char *name) > case RID_IS_EMPTY: > case RID_IS_ENUM: > case RID_IS_FINAL: >+ case RID_IS_LAYOUT_COMPATIBLE: > case RID_IS_LITERAL_TYPE: > case RID_IS_POD: > case RID_IS_POLYMORPHIC: >--- gcc/cp/constraint.cc.jj 2021-07-12 09:06:05.993356731 +0200 >+++ gcc/cp/constraint.cc 2021-07-21 10:58:06.874189921 +0200 >@@ -3649,6 +3649,9 @@ diagnose_trait_expr (tree expr, tree arg > case CPTK_IS_UNION: > inform (loc, " %qT is not a union", t1); > break; >+ case CPTK_IS_LAYOUT_COMPATIBLE: >+ inform (loc, " %qT is not layout compatible with %qT", t1, t2); >+ break; > default: > gcc_unreachable (); > } >--- gcc/cp/typeck.c.jj 2021-07-15 18:50:46.613901965 +0200 >+++ gcc/cp/typeck.c 2021-07-21 15:45:30.378947377 +0200 >@@ -1621,6 +1621,106 @@ similar_type_p (tree type1, tree type2) > return false; > } > >+/* Return true if TYPE1 and TYPE2 are layout-compatible types. */ >+ >+bool >+layout_compatible_type_p (tree type1, tree type2) >+{ >+ if (type1 == error_mark_node || type2 == error_mark_node) >+ return false; >+ if (type1 == type2) >+ return true; >+ if (TREE_CODE (type1) != TREE_CODE (type2)) >+ return false; >+ >+ type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED); >+ type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED); >+ >+ if (TREE_CODE (type1) == ENUMERAL_TYPE >+ && ENUM_UNDERLYING_TYPE (type1) >+ && ENUM_UNDERLYING_TYPE (type2)) >+ return same_type_p (ENUM_UNDERLYING_TYPE (type1), >+ ENUM_UNDERLYING_TYPE (type2)); >+ >+ if (CLASS_TYPE_P (type1) >+ && std_layout_type_p (type1) >+ && std_layout_type_p (type2)) >+ { >+ tree field1 = TYPE_FIELDS (type1); >+ tree field2 = TYPE_FIELDS (type2); >+ if (TREE_CODE (type1) == RECORD_TYPE) >+ { >+ while (1) >+ { >+ while (field1 && TREE_CODE (field1) != FIELD_DECL) >+ field1 = DECL_CHAIN (field1); >+ while (field2 && TREE_CODE (field2) != FIELD_DECL) >+ field2 = DECL_CHAIN (field2); >+ if (field1 == NULL_TREE && field2 == NULL_TREE) >+ return true; >+ if (field1 == NULL_TREE || field2 == NULL_TREE) >+ return false; >+ if (DECL_BIT_FIELD_TYPE (field1)) >+ { >+ if (!DECL_BIT_FIELD_TYPE (field2)) >+ return false; >+ if (!layout_compatible_type_p (DECL_BIT_FIELD_TYPE (field1), >+ DECL_BIT_FIELD_TYPE (field2))) >+ return false; >+ if (TYPE_PRECISION (TREE_TYPE (field1)) >+ != TYPE_PRECISION (TREE_TYPE (field2))) >+ return false; >+ } >+ else if (DECL_BIT_FIELD_TYPE (field2)) >+ return false; >+ else if (!layout_compatible_type_p (TREE_TYPE (field1), >+ TREE_TYPE (field2))) >+ return false; >+ if ((!lookup_attribute ("no_unique_address", >+ DECL_ATTRIBUTES (field1))) >+ != !lookup_attribute ("no_unique_address", >+ DECL_ATTRIBUTES (field2))) >+ return false; >+ field1 = DECL_CHAIN (field1); >+ field2 = DECL_CHAIN (field2); >+ } >+ } >+ auto_vec<tree, 16> vec; >+ unsigned int count = 0; >+ for (; field1; field1 = DECL_CHAIN (field1)) >+ if (TREE_CODE (field1) == FIELD_DECL) >+ count++; >+ for (; field2; field2 = DECL_CHAIN (field2)) >+ if (TREE_CODE (field2) == FIELD_DECL) >+ vec.safe_push (field2); >+ if (count != vec.length ()) >+ return false; >+ for (field1 = TYPE_FIELDS (type1); field1; field1 = DECL_CHAIN (field1)) >+ { >+ if (TREE_CODE (field1) != FIELD_DECL) >+ continue; >+ unsigned int j; >+ tree t1 = DECL_BIT_FIELD_TYPE (field1); >+ if (t1 == NULL_TREE) >+ t1 = TREE_TYPE (field1); >+ FOR_EACH_VEC_ELT (vec, j, field2) >+ { >+ tree t2 = DECL_BIT_FIELD_TYPE (field2); >+ if (t2 == NULL_TREE) >+ t2 = TREE_TYPE (field2); >+ if (layout_compatible_type_p (t1, t2)) >+ break; >+ } >+ if (j == vec.length ()) >+ return false; >+ vec.unordered_remove (j); >+ } >+ return true; >+ } >+ >+ return same_type_p (type1, type2); >+} >+ > /* Returns 1 if TYPE1 is at least as qualified as TYPE2. */ > > bool >--- gcc/cp/semantics.c.jj 2021-07-21 09:38:53.086875149 +0200 >+++ gcc/cp/semantics.c 2021-07-21 11:57:55.400348129 +0200 >@@ -10655,6 +10655,9 @@ trait_expr_value (cp_trait_kind kind, tr > case CPTK_IS_FINAL: > return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1); > >+ case CPTK_IS_LAYOUT_COMPATIBLE: >+ return layout_compatible_type_p (type1, type2); >+ > case CPTK_IS_LITERAL_TYPE: > return literal_type_p (type1); > >@@ -10796,6 +10799,7 @@ finish_trait_expr (location_t loc, cp_tr > case CPTK_IS_ENUM: > case CPTK_IS_UNION: > case CPTK_IS_SAME_AS: >+ case CPTK_IS_LAYOUT_COMPATIBLE: > break; > > default: >--- gcc/cp/cxx-pretty-print.c.jj 2021-04-26 09:54:53.821429440 +0200 >+++ gcc/cp/cxx-pretty-print.c 2021-07-21 10:57:07.363039195 +0200 >@@ -2645,6 +2645,9 @@ pp_cxx_trait_expression (cxx_pretty_prin > case CPTK_IS_FINAL: > pp_cxx_ws_string (pp, "__is_final"); > break; >+ case CPTK_IS_LAYOUT_COMPATIBLE: >+ pp_cxx_ws_string (pp, "__is_layout_compatible"); >+ break; > case CPTK_IS_POD: > pp_cxx_ws_string (pp, "__is_pod"); > break; >@@ -2695,7 +2698,9 @@ pp_cxx_trait_expression (cxx_pretty_prin > pp_cxx_left_paren (pp); > pp->type_id (TRAIT_EXPR_TYPE1 (t)); > >- if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS) >+ if (kind == CPTK_IS_BASE_OF >+ || kind == CPTK_IS_SAME_AS >+ || kind == CPTK_IS_LAYOUT_COMPATIBLE) > { > pp_cxx_separate_with (pp, ','); > pp->type_id (TRAIT_EXPR_TYPE2 (t)); >--- gcc/testsuite/g++.dg/cpp2a/is-layout-compatible1.C.jj 2021-07-21 15:49:04.020966625 +0200 >+++ gcc/testsuite/g++.dg/cpp2a/is-layout-compatible1.C 2021-07-21 15:48:34.078384387 +0200 >@@ -0,0 +1,75 @@ >+// P0466R5 >+// { dg-do compile { target c++20 } } >+ >+namespace std >+{ >+template <typename T, T v> >+struct integral_constant >+{ >+ static constexpr T value = v; >+}; >+ >+template <typename, typename> >+struct is_layout_compatible; >+ >+template<typename T, typename U> >+struct is_layout_compatible >+ : public integral_constant <bool, __is_layout_compatible (T, U)> >+{ >+}; >+ >+template <typename T, typename U> >+inline constexpr bool is_layout_compatible_v = __is_layout_compatible (T, U); >+} >+ >+struct A { int a; char b; }; >+struct B { const int c; volatile char d; }; >+struct C { int a : 1; int : 7; int : 0; int b : 2; }; >+struct D { int : 1; int c : 7; int : 0; int : 2; }; >+struct E { int f : 1; int : 7; int g : 2; }; >+struct F { int a; signed char b; }; >+union G { int a; long long b; signed char c; unsigned char d; int e; }; >+union H { long long f; unsigned char g; int h; int i; signed char j; }; >+struct S {}; >+struct T {}; >+struct W; >+struct X; >+ >+static_assert (std::is_layout_compatible<int, const int>::value); >+static_assert (std::is_layout_compatible_v<double, volatile double>); >+static_assert (std::is_layout_compatible_v<A, B>); >+static_assert (std::is_layout_compatible_v<C, D>); >+static_assert (!std::is_layout_compatible_v<int, unsigned int>); >+static_assert (!std::is_layout_compatible_v<A, F>); >+static_assert (std::is_layout_compatible_v<G, H>); >+static_assert (std::is_layout_compatible_v<S, T>); >+static_assert (std::is_layout_compatible_v<A[3], A[3]>); >+static_assert (std::is_layout_compatible_v<A[], A[]>); >+static_assert (!std::is_layout_compatible_v<S[1], T[1]>); >+static_assert (std::is_layout_compatible_v<W[], W[]>); >+static_assert (!std::is_layout_compatible_v<W[], X[]>); >+// FIXME: BUG, should be ! - the FE unfortunately invokes >+// remove_zero_width_bit_fields before we get the chance to see >+// them for __is_layout_compatible. >+static_assert (std::is_layout_compatible_v<D, E>); >+ >+// Unexpected and weird cases. >+struct I { int a; }; >+struct alignas(16) J { const int b; }; >+struct K { I c; int d; }; >+struct L { J e; int f; }; >+union M { I u; }; >+union N { J v; }; >+union O { int a; int b; }; >+union P { int a : 1; int b : 12; }; >+enum Q : int { Q1, Q2 }; >+enum alignas(16) R : int { R1, R2 }; >+struct U { [[no_unique_address]] S a1; [[no_unique_address]] S a2; [[no_unique_address]] S a3; }; >+struct V { [[no_unique_address]] S b1; [[no_unique_address]] T b2; [[no_unique_address]] S b3; }; >+ >+static_assert (std::is_layout_compatible_v<I, J>); >+static_assert (std::is_layout_compatible_v<K, L>); >+static_assert (std::is_layout_compatible_v<M, N>); >+static_assert (std::is_layout_compatible_v<O, P>); >+static_assert (std::is_layout_compatible_v<Q, R>); >+static_assert (std::is_layout_compatible_v<U, V>);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 101539
:
51186
|
51192
|
51219
|
51241