Hi! Trivial relocation was voted out of C++26, the following patch removes it (note, the libstdc++ part was still waiting for patch review and so doesn't need to be removed).
This isn't a mere revert of r16-2206; I've kept -Wc++26-compat option, from earlier patches the non-terminal stays to be class-property-specifier, and I had to partially revert also various follow-up changes, e.g. for modules to handle the new flags and test them, for -Wkeyword-macro etc. to diagnose the conditional keywords or the feature test macro etc. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-11-10 Jakub Jelinek <[email protected]> PR c++/119064 gcc/c-family/ * c-cppbuiltin.cc (c_cpp_builtins): Revert 2025-07-11 changes. gcc/cp/ * cp-tree.h (struct lang_type): Revert 2025-07-11 changes. (CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT): Remove. (CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED): Remove. (CLASSTYPE_REPLACEABLE_BIT): Remove. (CLASSTYPE_REPLACEABLE_COMPUTED): Remove. (enum virt_specifier): Revert 2025-07-11 changes. (trivially_relocatable_type_p): Remove. (replaceable_type_p): Remove. * cp-trait.def (IS_NOTHROW_RELOCATABLE): Remove. (IS_REPLACEABLE): Remove. (IS_TRIVIALLY_RELOCATABLE): Remove. * parser.cc (cp_parser_class_specifier, cp_parser_class_head): Revert 2025-07-11 changes. * pt.cc (instantiate_class_template): Likewise. * semantics.cc (trait_expr_value): Likewise. (finish_trait_expr): Likewise. * tree.cc (default_movable_type_p): Remove. (union_with_no_declared_special_member_fns): Remove. (trivially_relocatable_type_p): Remove. (replaceable_type_p): Remove. * constraint.cc (diagnose_trait_expr): Revert 2025-07-11 changes. * module.cc (trees_out::lang_type_bools): Revert part of 2025-07-26 changes related to trivial relocatability. (trees_in::lang_type_bools): Likewise. * lex.cc (cxx_init): Don't call cpp_warn on trivially_relocatable_if_eligible and replaceable_if_eligible. gcc/testsuite/ * g++.dg/cpp26/feat-cxx26.C: Revert 2025-07-11 changes. * g++.dg/DRs/dr2581-1.C (__cpp_trivial_relocatability): Remove test. * g++.dg/DRs/dr2581-2.C (__cpp_trivial_relocatability): Likewise. * g++.dg/warn/Wkeyword-macro-1.C: Don't expect any diagnostics on #define or #undef of trivially_relocatable_if_eligible or replaceable_if_eligible. * g++.dg/warn/Wkeyword-macro-2.C: Likewise. * g++.dg/warn/Wkeyword-macro-4.C: Likewise. * g++.dg/warn/Wkeyword-macro-5.C: Likewise. * g++.dg/warn/Wkeyword-macro-7.C: Likewise. * g++.dg/warn/Wkeyword-macro-8.C: Likewise. * g++.dg/cpp26/trivially-relocatable1.C: Remove. * g++.dg/cpp26/trivially-relocatable2.C: Remove. * g++.dg/cpp26/trivially-relocatable3.C: Remove. * g++.dg/cpp26/trivially-relocatable4.C: Remove. * g++.dg/cpp26/trivially-relocatable5.C: Remove. * g++.dg/cpp26/trivially-relocatable6.C: Remove. * g++.dg/cpp26/trivially-relocatable7.C: Remove. * g++.dg/cpp26/trivially-relocatable8.C: Remove. * g++.dg/cpp26/trivially-relocatable9.C: Remove. * g++.dg/cpp26/trivially-relocatable10.C: Remove. * g++.dg/cpp26/trivially-relocatable11.C: Remove. * g++.dg/modules/class-11_a.H: Remove trivial relocatability related parts. * g++.dg/modules/class-11_b.C: Likewise. --- gcc/c-family/c-cppbuiltin.cc.jj 2025-11-08 10:09:48.210340088 +0100 +++ gcc/c-family/c-cppbuiltin.cc 2025-11-08 10:18:49.260618029 +0100 @@ -1115,7 +1115,6 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_pack_indexing=202311L"); cpp_define (pfile, "__cpp_pp_embed=202502L"); cpp_define (pfile, "__cpp_constexpr_virtual_inheritance=202506L"); - cpp_define (pfile, "__cpp_trivial_relocatability=202502L"); cpp_define (pfile, "__cpp_expansion_statements=202506L"); } if (flag_concepts && cxx_dialect > cxx14) --- gcc/cp/cp-tree.h.jj 2025-11-07 10:35:07.244570810 +0100 +++ gcc/cp/cp-tree.h 2025-11-08 10:10:52.259425966 +0100 @@ -2523,11 +2523,6 @@ struct GTY(()) lang_type { bool erroneous : 1; bool non_pod_aggregate : 1; bool non_aggregate_pod : 1; - bool trivially_relocatable : 1; - bool trivially_relocatable_computed : 1; - - bool replaceable : 1; - bool replaceable_computed : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If @@ -2538,7 +2533,7 @@ struct GTY(()) lang_type { /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ - unsigned dummy : 30; + unsigned dummy : 2; tree primary_base; vec<tree_pair_s, va_gc> *vcall_indices; @@ -2885,29 +2880,6 @@ struct GTY(()) lang_type { above (c++/120012). This could also be a hash_set. */ #define CLASSTYPE_NON_AGGREGATE_POD(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate_pod) - -/* If CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, true if this class is - trivially relocatable. - If !CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, true if this class - is marked with trivially_relocatable_if_eligible conditional keyword. */ -#define CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->trivially_relocatable) - -/* True if whether this class is trivially relocatable or not - has been computed already. */ -#define CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->trivially_relocatable_computed) - -/* If CLASSTYPE_REPLACEABLE_COMPUTED, true if this class is replaceable. - If !CLASSTYPE_REPLACEABLE_COMPUTED, true if this class is marked with - replaceable_if_eligible conditional keyword. */ -#define CLASSTYPE_REPLACEABLE_BIT(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->replaceable) - -/* True if whether this class is replaceable or not has been computed - already. */ -#define CLASSTYPE_REPLACEABLE_COMPUTED(NODE) \ - (LANG_TYPE_CLASS_CHECK (NODE)->replaceable_computed) /* Additional macros for inheritance information. */ @@ -6577,9 +6549,7 @@ enum virt_specifier { VIRT_SPEC_UNSPECIFIED = 0x0, VIRT_SPEC_FINAL = 0x1, - VIRT_SPEC_OVERRIDE = 0x2, - VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE = 0x4, - VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE = 0x8 + VIRT_SPEC_OVERRIDE = 0x2 }; /* A type-qualifier, or bitmask therefore, using the VIRT_SPEC @@ -8376,8 +8346,6 @@ extern bool pod_type_p (const_tree); extern bool layout_pod_type_p (const_tree); extern bool std_layout_type_p (const_tree); extern bool trivial_type_p (const_tree); -extern bool trivially_relocatable_type_p (tree); -extern bool replaceable_type_p (tree); extern bool implicit_lifetime_type_p (tree); extern bool trivially_copyable_p (const_tree); extern bool type_has_unique_obj_representations (const_tree); --- gcc/cp/cp-trait.def.jj 2025-10-21 19:17:04.328041752 +0200 +++ gcc/cp/cp-trait.def 2025-11-08 10:09:55.424237138 +0100 @@ -88,14 +88,12 @@ DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2) DEFTRAIT_EXPR (IS_NOTHROW_DESTRUCTIBLE, "__is_nothrow_destructible", 1) DEFTRAIT_EXPR (IS_NOTHROW_INVOCABLE, "__is_nothrow_invocable", -1) -DEFTRAIT_EXPR (IS_NOTHROW_RELOCATABLE, "__builtin_is_nothrow_relocatable", 1) DEFTRAIT_EXPR (IS_OBJECT, "__is_object", 1) DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, "__is_pointer_interconvertible_base_of", 2) DEFTRAIT_EXPR (IS_POD, "__is_pod", 1) DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 1) DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1) DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1) -DEFTRAIT_EXPR (IS_REPLACEABLE, "__builtin_is_replaceable", 1) DEFTRAIT_EXPR (IS_SAME, "__is_same", 2) DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1) DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1) @@ -104,7 +102,6 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1) DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1) DEFTRAIT_EXPR (IS_TRIVIALLY_DESTRUCTIBLE, "__is_trivially_destructible", 1) -DEFTRAIT_EXPR (IS_TRIVIALLY_RELOCATABLE, "__builtin_is_trivially_relocatable", 1) DEFTRAIT_EXPR (IS_UNBOUNDED_ARRAY, "__is_unbounded_array", 1) DEFTRAIT_EXPR (IS_UNION, "__is_union", 1) DEFTRAIT_EXPR (IS_VIRTUAL_BASE_OF, "__builtin_is_virtual_base_of", 2) --- gcc/cp/parser.cc.jj 2025-11-07 10:35:07.321569735 +0100 +++ gcc/cp/parser.cc 2025-11-08 10:09:55.435236981 +0100 @@ -28721,8 +28721,6 @@ cp_parser_class_specifier (cp_parser* pa class-property-specifier: final - trivially_relocatable_if_eligible (C++26) - replaceable_if_eligible (C++26) Returns a bitmask representing the class-property-specifiers. */ @@ -28755,38 +28753,6 @@ cp_parser_class_property_specifier_seq_o } else if (id_equal (token->u.value, "__final")) virt_specifier = VIRT_SPEC_FINAL; - else if (id_equal (token->u.value, "trivially_relocatable_if_eligible")) - { - if (cxx_dialect < cxx26) - { - /* Warn about the C++26 conditional keyword (but don't parse - it). */ - warning_at (token->location, OPT_Wc__26_compat, - "identifier %qE is a conditional keyword in C++26", - token->u.value); - break; - } - virt_specifier = VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE; - } - else if (id_equal (token->u.value, - "__trivially_relocatable_if_eligible")) - virt_specifier = VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE; - else if (id_equal (token->u.value, "replaceable_if_eligible")) - { - if (cxx_dialect < cxx26) - { - /* Warn about the C++26 conditional keyword (but don't parse - it). */ - warning_at (token->location, OPT_Wc__26_compat, - "identifier %qE is a conditional keyword in C++26", - token->u.value); - break; - } - virt_specifier = VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE; - } - else if (id_equal (token->u.value, - "__replaceable_if_eligible")) - virt_specifier = VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE; else break; @@ -29342,16 +29308,6 @@ cp_parser_class_head (cp_parser* parser, DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location; if (type && (virt_specifiers & VIRT_SPEC_FINAL)) CLASSTYPE_FINAL (type) = 1; - if (type && (virt_specifiers & VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE)) - { - gcc_assert (!CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (type)); - CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (type) = 1; - } - if (type && (virt_specifiers & VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE)) - { - gcc_assert (!CLASSTYPE_REPLACEABLE_COMPUTED (type)); - CLASSTYPE_REPLACEABLE_BIT (type) = 1; - } out: parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; return type; --- gcc/cp/pt.cc.jj 2025-11-07 10:35:07.386568827 +0100 +++ gcc/cp/pt.cc 2025-11-08 10:09:55.441236895 +0100 @@ -12708,17 +12708,7 @@ instantiate_class_template (tree type) determine_visibility (TYPE_MAIN_DECL (type)); } if (CLASS_TYPE_P (type)) - { - CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); - CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (type) - = CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (pattern); - CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (type) - = CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (pattern); - CLASSTYPE_REPLACEABLE_BIT (type) - = CLASSTYPE_REPLACEABLE_BIT (pattern); - CLASSTYPE_REPLACEABLE_COMPUTED (type) - = CLASSTYPE_REPLACEABLE_COMPUTED (pattern); - } + CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern); pbinfo = TYPE_BINFO (pattern); --- gcc/cp/semantics.cc.jj 2025-10-21 19:17:04.406040715 +0200 +++ gcc/cp/semantics.cc 2025-11-08 10:09:55.443236867 +0100 @@ -13631,21 +13631,6 @@ trait_expr_value (cp_trait_kind kind, tr case CPTK_IS_NOTHROW_INVOCABLE: return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none); - case CPTK_IS_NOTHROW_RELOCATABLE: - if (trivially_relocatable_type_p (type1)) - return true; - else - { - type1 = strip_array_types (type1); - if (!referenceable_type_p (type1)) - return false; - tree arg = make_tree_vec (1); - TREE_VEC_ELT (arg, 0) - = cp_build_reference_type (type1, /*rval=*/true); - return (is_nothrow_xible (INIT_EXPR, type1, arg) - && is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE)); - } - case CPTK_IS_OBJECT: return object_type_p (type1); @@ -13664,9 +13649,6 @@ trait_expr_value (cp_trait_kind kind, tr case CPTK_IS_REFERENCE: return type_code1 == REFERENCE_TYPE; - case CPTK_IS_REPLACEABLE: - return replaceable_type_p (type1); - case CPTK_IS_SAME: return same_type_p (type1, type2); @@ -13691,9 +13673,6 @@ trait_expr_value (cp_trait_kind kind, tr case CPTK_IS_TRIVIALLY_DESTRUCTIBLE: return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE); - case CPTK_IS_TRIVIALLY_RELOCATABLE: - return trivially_relocatable_type_p (type1); - case CPTK_IS_UNBOUNDED_ARRAY: return array_of_unknown_bound_p (type1); @@ -13895,11 +13874,8 @@ finish_trait_expr (location_t loc, cp_tr case CPTK_IS_LITERAL_TYPE: case CPTK_IS_POD: case CPTK_IS_STD_LAYOUT: - case CPTK_IS_REPLACEABLE: - case CPTK_IS_NOTHROW_RELOCATABLE: case CPTK_IS_TRIVIAL: case CPTK_IS_TRIVIALLY_COPYABLE: - case CPTK_IS_TRIVIALLY_RELOCATABLE: case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: if (!check_trait_type (type1, /* kind = */ 2)) return error_mark_node; --- gcc/cp/tree.cc.jj 2025-11-08 10:09:58.391194793 +0100 +++ gcc/cp/tree.cc 2025-11-08 10:12:01.693434980 +0100 @@ -4810,293 +4810,6 @@ trivial_type_p (const_tree t) return scalarish_type_p (t); } -/* Returns 1 iff type T is a default-movable type, as defined in - [class.prop]. */ - -static bool -default_movable_type_p (tree t) -{ - if (!CLASS_TYPE_P (t) || !COMPLETE_TYPE_P (t)) - return false; - if (CLASSTYPE_LAZY_DESTRUCTOR (t)) - lazily_declare_fn (sfk_destructor, t); - if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) - if (user_provided_p (dtor) || DECL_DELETED_FN (dtor)) - return false; - - tree copy_ctor = NULL_TREE, move_ctor = NULL_TREE; - tree copy_assign = NULL_TREE, move_assign = NULL_TREE; - if (CLASSTYPE_LAZY_MOVE_CTOR (t)) - move_ctor = lazily_declare_fn (sfk_move_constructor, t); - if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) - move_assign = lazily_declare_fn (sfk_move_assignment, t); - if (!move_ctor) - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) - if (TREE_CODE (*iter) == FUNCTION_DECL) - { - if (copy_fn_p (*iter)) - copy_ctor = *iter; - else if (move_fn_p (*iter)) - { - move_ctor = *iter; - break; - } - } - if (!move_assign) - for (ovl_iterator iter (get_class_binding_direct (t, - assign_op_identifier)); - iter; ++iter) - if (TREE_CODE (*iter) == FUNCTION_DECL) - { - if (copy_fn_p (*iter)) - copy_assign = *iter; - else if (move_fn_p (*iter)) - { - move_assign = *iter; - break; - } - } - if (!move_ctor) - { - if (CLASSTYPE_LAZY_COPY_CTOR (t)) - copy_ctor = lazily_declare_fn (sfk_copy_constructor, t); - if (!copy_ctor) - return false; - if (user_provided_p (copy_ctor) - || DECL_DELETED_FN (copy_ctor) - || DECL_CONTEXT (copy_ctor) != t - || DECL_INHERITED_CTOR (copy_ctor)) - return false; - } - else if (user_provided_p (move_ctor) - || DECL_DELETED_FN (move_ctor) - || DECL_CONTEXT (move_ctor) != t - || DECL_INHERITED_CTOR (move_ctor)) - return false; - if (!move_assign) - { - if (CLASSTYPE_LAZY_COPY_ASSIGN (t)) - copy_assign = lazily_declare_fn (sfk_copy_assignment, t); - if (!copy_assign) - return false; - if (user_provided_p (copy_assign) - || DECL_DELETED_FN (copy_assign) - || DECL_CONTEXT (copy_assign) != t) - return false; - } - else if (user_provided_p (move_assign) - || DECL_DELETED_FN (move_assign) - || DECL_CONTEXT (move_assign) != t) - return false; - return true; -} - -/* Returns 1 iff type T is a union with no user declared special member - functions. */ - -static bool -union_with_no_declared_special_member_fns (tree t) -{ - if (TREE_CODE (t) != UNION_TYPE) - return false; - - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) - if (TREE_CODE (*iter) == FUNCTION_DECL - && !DECL_ARTIFICIAL (*iter) - && (default_ctor_p (*iter) || copy_fn_p (*iter) || move_fn_p (*iter))) - return false; - - for (ovl_iterator iter (get_class_binding_direct (t, assign_op_identifier)); - iter; ++iter) - if (TREE_CODE (*iter) == FUNCTION_DECL - && !DECL_ARTIFICIAL (*iter) - && (copy_fn_p (*iter) || move_fn_p (*iter))) - return false; - - if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) - if (!DECL_ARTIFICIAL (dtor)) - return false; - - return true; -} - -/* Returns 1 iff type T is a trivially relocatable type, as defined in - [basic.types.general] and [class.prop]. */ - -bool -trivially_relocatable_type_p (tree t) -{ - t = strip_array_types (t); - - if (!CLASS_TYPE_P (t)) - return scalarish_type_p (t); - - t = TYPE_MAIN_VARIANT (t); - if (CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (t)) - return CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t); - if (!COMPLETE_TYPE_P (t)) - return false; - - if (!CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t) - && !union_with_no_declared_special_member_fns (t) - && !default_movable_type_p (t)) - { - nontriv: - CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t) = 0; - CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (t) = 1; - return false; - } - - if (CLASSTYPE_VBASECLASSES (t)) - goto nontriv; - - if (CLASSTYPE_LAZY_DESTRUCTOR (t)) - lazily_declare_fn (sfk_destructor, t); - if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) - if (DECL_DELETED_FN (dtor)) - goto nontriv; - - tree binfo, base_binfo; - unsigned int i; - for (binfo = TYPE_BINFO (t), i = 0; - BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - { - tree basetype = TREE_TYPE (base_binfo); - if (!trivially_relocatable_type_p (basetype)) - goto nontriv; - } - - for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL - && !DECL_ARTIFICIAL (field) - && !DECL_UNNAMED_BIT_FIELD (field)) - { - tree type = TREE_TYPE (field); - if (type == error_mark_node) - goto nontriv; - if (!TYPE_REF_P (type) && !trivially_relocatable_type_p (type)) - goto nontriv; - } - - CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT (t) = 1; - CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED (t) = 1; - return true; -} - -/* Returns 1 iff type T is a replaceable type, as defined in [basic.types] - and [class]. */ - -bool -replaceable_type_p (tree t) -{ - t = strip_array_types (t); - - if (cv_qualified_p (t)) - return false; - - if (!CLASS_TYPE_P (t)) - return scalarish_type_p (t); - - t = TYPE_MAIN_VARIANT (t); - if (CLASSTYPE_REPLACEABLE_COMPUTED (t)) - return CLASSTYPE_REPLACEABLE_BIT (t); - if (!COMPLETE_TYPE_P (t)) - return false; - - if (!CLASSTYPE_REPLACEABLE_BIT (t) - && !union_with_no_declared_special_member_fns (t) - && !default_movable_type_p (t)) - { - nonrepl: - CLASSTYPE_REPLACEABLE_BIT (t) = 0; - CLASSTYPE_REPLACEABLE_COMPUTED (t) = 1; - return false; - } - - if (CLASSTYPE_LAZY_DESTRUCTOR (t)) - lazily_declare_fn (sfk_destructor, t); - if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) - if (DECL_DELETED_FN (dtor)) - goto nonrepl; - - tree copy_ctor = NULL_TREE, move_ctor = NULL_TREE; - tree copy_assign = NULL_TREE, move_assign = NULL_TREE; - if (CLASSTYPE_LAZY_MOVE_CTOR (t)) - move_ctor = lazily_declare_fn (sfk_move_constructor, t); - if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) - move_assign = lazily_declare_fn (sfk_move_assignment, t); - if (!move_ctor) - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) - if (TREE_CODE (*iter) == FUNCTION_DECL) - { - if (copy_fn_p (*iter)) - copy_ctor = *iter; - else if (move_fn_p (*iter)) - { - move_ctor = *iter; - break; - } - } - if (!move_assign) - for (ovl_iterator iter (get_class_binding_direct (t, - assign_op_identifier)); - iter; ++iter) - if (TREE_CODE (*iter) == FUNCTION_DECL) - { - if (copy_fn_p (*iter)) - copy_assign = *iter; - else if (move_fn_p (*iter)) - { - move_assign = *iter; - break; - } - } - if (!move_ctor) - { - if (CLASSTYPE_LAZY_COPY_CTOR (t)) - copy_ctor = lazily_declare_fn (sfk_copy_constructor, t); - if (!copy_ctor || DECL_DELETED_FN (copy_ctor)) - goto nonrepl; - } - else if (DECL_DELETED_FN (move_ctor)) - goto nonrepl; - if (!move_assign) - { - if (CLASSTYPE_LAZY_COPY_ASSIGN (t)) - copy_assign = lazily_declare_fn (sfk_copy_assignment, t); - if (!copy_assign || DECL_DELETED_FN (copy_assign)) - goto nonrepl; - } - else if (DECL_DELETED_FN (move_assign)) - goto nonrepl; - - tree binfo, base_binfo; - unsigned int i; - for (binfo = TYPE_BINFO (t), i = 0; - BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - { - tree basetype = TREE_TYPE (base_binfo); - if (!replaceable_type_p (basetype)) - goto nonrepl; - } - - for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL - && !DECL_ARTIFICIAL (field) - && !DECL_UNNAMED_BIT_FIELD (field)) - { - tree type = TREE_TYPE (field); - if (type == error_mark_node) - goto nonrepl; - if (!replaceable_type_p (type)) - goto nonrepl; - } - - CLASSTYPE_REPLACEABLE_BIT (t) = 1; - CLASSTYPE_REPLACEABLE_COMPUTED (t) = 1; - return true; -} - /* Returns 1 iff type T is an implicit-lifetime type, as defined in [basic.types.general] and [class.prop]. */ --- gcc/cp/constraint.cc.jj 2025-11-08 10:09:55.423237152 +0100 +++ gcc/cp/constraint.cc 2025-11-08 10:10:30.203740751 +0100 @@ -3228,9 +3228,6 @@ diagnose_trait_expr (location_t loc, tre explain_not_noexcept (call); } break; - case CPTK_IS_NOTHROW_RELOCATABLE: - inform (loc, "%qT is not nothrow relocatable", t1); - break; case CPTK_IS_OBJECT: inform (loc, "%qT is not an object type", t1); break; @@ -3250,9 +3247,6 @@ diagnose_trait_expr (location_t loc, tre case CPTK_IS_REFERENCE: inform (loc, "%qT is not a reference", t1); break; - case CPTK_IS_REPLACEABLE: - inform (loc, "%qT is not replaceable", t1); - break; case CPTK_IS_SAME: inform (loc, "%q#T is not the same as %q#T", t1, t2); break; @@ -3284,9 +3278,6 @@ diagnose_trait_expr (location_t loc, tre inform (loc, "%qT is not trivially destructible, because", t1); is_trivially_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true); break; - case CPTK_IS_TRIVIALLY_RELOCATABLE: - inform (loc, "%qT is not trivially relocatable", t1); - break; case CPTK_IS_UNBOUNDED_ARRAY: inform (loc, "%qT is not an unbounded array", t1); break; --- gcc/cp/module.cc.jj 2025-11-07 10:35:07.273570405 +0100 +++ gcc/cp/module.cc 2025-11-08 10:15:06.434798282 +0100 @@ -6235,11 +6235,6 @@ trees_out::lang_type_bools (tree t, bits gcc_checking_assert (!lang->erroneous); WB (lang->non_pod_aggregate); WB (lang->non_aggregate_pod); - WB (lang->trivially_relocatable); - WB (lang->trivially_relocatable_computed); - - WB (lang->replaceable); - WB (lang->replaceable_computed); #undef WB } @@ -6313,11 +6308,6 @@ trees_in::lang_type_bools (tree t, bits_ gcc_checking_assert (!lang->erroneous); RB (lang->non_pod_aggregate); RB (lang->non_aggregate_pod); - RB (lang->trivially_relocatable); - RB (lang->trivially_relocatable_computed); - - RB (lang->replaceable); - RB (lang->replaceable_computed); #undef RB return !get_overrun (); } --- gcc/cp/lex.cc.jj 2025-11-08 09:51:49.579670861 +0100 +++ gcc/cp/lex.cc 2025-11-08 10:11:09.946173529 +0100 @@ -419,11 +419,7 @@ cxx_init (void) if (cxx_dialect >= cxx23) cpp_warn (parse_in, "assume"); if (cxx_dialect >= cxx26) - { - cpp_warn (parse_in, "replaceable_if_eligible"); - cpp_warn (parse_in, "trivially_relocatable_if_eligible"); - cpp_warn (parse_in, "indeterminate"); - } + cpp_warn (parse_in, "indeterminate"); } if (c_common_init () == false) --- gcc/testsuite/g++.dg/cpp26/feat-cxx26.C.jj 2025-08-13 22:10:18.897791624 +0200 +++ gcc/testsuite/g++.dg/cpp26/feat-cxx26.C 2025-11-08 10:24:15.663959960 +0100 @@ -647,12 +647,6 @@ # error "__cpp_constexpr_exceptions != 202411" #endif -#ifndef __cpp_trivial_relocatability -# error "__cpp_trivial_relocatability" -#elif __cpp_trivial_relocatability != 202502 -# error "__cpp_trivial_relocatability != 202502" -#endif - #ifndef __cpp_expansion_statements # error "__cpp_expansion_statements" #elif __cpp_expansion_statements != 202506 --- gcc/testsuite/g++.dg/DRs/dr2581-1.C.jj 2025-08-15 22:31:17.264081465 +0200 +++ gcc/testsuite/g++.dg/DRs/dr2581-1.C 2025-11-08 18:27:59.395575371 +0100 @@ -94,7 +94,6 @@ #undef __cpp_template_parameters #undef __cpp_template_template_args // { dg-warning "undefining '__cpp_template_template_args'" "" { target c++20 } } #undef __cpp_threadsafe_static_init // { dg-warning "undefining '__cpp_threadsafe_static_init'" "" { target c++20 } } -#undef __cpp_trivial_relocatability // { dg-warning "undefining '__cpp_trivial_relocatability'" "" { target c++26 } } #undef __cpp_trivial_union #undef __cpp_unicode_characters // { dg-warning "undefining '__cpp_unicode_characters'" "" { target c++20 } } #undef __cpp_unicode_literals // { dg-warning "undefining '__cpp_unicode_literals'" "" { target c++20 } } --- gcc/testsuite/g++.dg/DRs/dr2581-2.C.jj 2025-08-15 22:31:17.264081465 +0200 +++ gcc/testsuite/g++.dg/DRs/dr2581-2.C 2025-11-08 18:28:09.454419495 +0100 @@ -94,7 +94,6 @@ #define __cpp_template_parameters 202502L #define __cpp_template_template_args 201611L // { dg-error "'__cpp_template_template_args' redefined" "" { target c++20 } } #define __cpp_threadsafe_static_init 200806L // { dg-error "'__cpp_threadsafe_static_init' redefined" "" { target c++20 } } -#define __cpp_trivial_relocatability 202502L // { dg-error "'__cpp_trivial_relocatability' redefined" "" { target c++26 } } #define __cpp_trivial_union 202502L #define __cpp_unicode_characters 200704L // { dg-error "'__cpp_unicode_characters' redefined" "" { target c++17 } } #define __cpp_unicode_literals 200710L // { dg-error "'__cpp_unicode_literals' redefined" "" { target c++20 } } --- gcc/testsuite/g++.dg/warn/Wkeyword-macro-1.C.jj 2025-11-08 09:52:37.366992249 +0100 +++ gcc/testsuite/g++.dg/warn/Wkeyword-macro-1.C 2025-11-08 10:14:03.835691718 +0100 @@ -95,8 +95,8 @@ #define override 1 // { dg-error "keyword 'override' defined as macro" "" { target c++26 } } #define post 1 #define pre 1 -#define replaceable_if_eligible 1 // { dg-error "keyword 'replaceable_if_eligible' defined as macro" "" { target c++26 } } -#define trivially_relocatable_if_eligible 1 // { dg-error "keyword 'trivially_relocatable_if_eligible' defined as macro" "" { target c++26 } } +#define replaceable_if_eligible +#define trivially_relocatable_if_eligible // [dcl.attr] #define assume 1 // { dg-error "keyword 'assume' defined as macro" "" { target c++26 } } --- gcc/testsuite/g++.dg/warn/Wkeyword-macro-2.C.jj 2025-11-08 09:53:01.971642849 +0100 +++ gcc/testsuite/g++.dg/warn/Wkeyword-macro-2.C 2025-11-08 10:14:06.813649219 +0100 @@ -95,8 +95,8 @@ #define override 1 // { dg-warning "keyword 'override' defined as macro" "" { target c++26 } } #define post 1 #define pre 1 -#define replaceable_if_eligible 1 // { dg-warning "keyword 'replaceable_if_eligible' defined as macro" "" { target c++26 } } -#define trivially_relocatable_if_eligible 1 // { dg-warning "keyword 'trivially_relocatable_if_eligible' defined as macro" "" { target c++26 } } +#define replaceable_if_eligible +#define trivially_relocatable_if_eligible // [dcl.attr] #define assume 1 // { dg-warning "keyword 'assume' defined as macro" "" { target c++26 } } --- gcc/testsuite/g++.dg/warn/Wkeyword-macro-4.C.jj 2025-11-08 09:53:29.352254032 +0100 +++ gcc/testsuite/g++.dg/warn/Wkeyword-macro-4.C 2025-11-08 10:13:57.924776084 +0100 @@ -95,8 +95,8 @@ #undef override // { dg-error "undefining keyword 'override'" "" { target c++26 } } #undef post #undef pre -#undef replaceable_if_eligible // { dg-error "undefining keyword 'replaceable_if_eligible'" "" { target c++26 } } -#undef trivially_relocatable_if_eligible // { dg-error "undefining keyword 'trivially_relocatable_if_eligible'" "" { target c++26 } } +#undef replaceable_if_eligible +#undef trivially_relocatable_if_eligible // [dcl.attr] #undef assume // { dg-error "undefining keyword 'assume'" "" { target c++26 } } --- gcc/testsuite/g++.dg/warn/Wkeyword-macro-5.C.jj 2025-11-08 09:54:01.078803495 +0100 +++ gcc/testsuite/g++.dg/warn/Wkeyword-macro-5.C 2025-11-08 10:14:00.940733038 +0100 @@ -95,8 +95,8 @@ #undef override // { dg-warning "undefining keyword 'override'" "" { target c++26 } } #undef post #undef pre -#undef replaceable_if_eligible // { dg-warning "undefining keyword 'replaceable_if_eligible'" "" { target c++26 } } -#undef trivially_relocatable_if_eligible // { dg-warning "undefining keyword 'trivially_relocatable_if_eligible'" "" { target c++26 } } +#undef replaceable_if_eligible +#undef trivially_relocatable_if_eligible // [dcl.attr] #undef assume // { dg-warning "undefining keyword 'assume'" "" { target c++26 } } --- gcc/testsuite/g++.dg/warn/Wkeyword-macro-7.C.jj 2025-11-08 09:54:54.396046360 +0100 +++ gcc/testsuite/g++.dg/warn/Wkeyword-macro-7.C 2025-11-08 10:14:09.826606213 +0100 @@ -95,8 +95,8 @@ #define override 1 // { dg-warning "keyword 'override' defined as macro" "" { target c++11 } } #define post 1 #define pre 1 -#define replaceable_if_eligible 1 // { dg-warning "keyword 'replaceable_if_eligible' defined as macro" "" { target c++26 } } -#define trivially_relocatable_if_eligible 1 // { dg-warning "keyword 'trivially_relocatable_if_eligible' defined as macro" "" { target c++26 } } +#define replaceable_if_eligible +#define trivially_relocatable_if_eligible // [dcl.attr] #define assume 1 // { dg-warning "keyword 'assume' defined as macro" "" { target c++23 } } --- gcc/testsuite/g++.dg/warn/Wkeyword-macro-8.C.jj 2025-11-08 09:55:15.758742999 +0100 +++ gcc/testsuite/g++.dg/warn/Wkeyword-macro-8.C 2025-11-08 10:13:53.972832482 +0100 @@ -95,8 +95,8 @@ #undef override // { dg-warning "undefining keyword 'override'" "" { target c++11 } } #undef post #undef pre -#undef replaceable_if_eligible // { dg-warning "undefining keyword 'replaceable_if_eligible'" "" { target c++26 } } -#undef trivially_relocatable_if_eligible // { dg-warning "undefining keyword 'trivially_relocatable_if_eligible'" "" { target c++26 } } +#undef replaceable_if_eligible +#undef trivially_relocatable_if_eligible // [dcl.attr] #undef assume // { dg-warning "undefining keyword 'assume'" "" { target c++23 } } --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable1.C.jj 2025-07-11 19:01:25.979530617 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable1.C 2025-11-08 10:13:00.536595150 +0100 @@ -1,137 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -struct A {}; - -static_assert (std::is_trivially_relocatable_v <A>, ""); -static_assert (std::is_replaceable_v <A>, ""); - -struct B { - B (); - ~B (); - B (const B &); - B (B &&); - B &operator= (const B &); - B &operator= (B &&); -}; - -static_assert (!std::is_trivially_relocatable_v <B>, ""); -static_assert (!std::is_replaceable_v <B>, ""); - -struct C { - C (C &&) = delete; - C &operator= (C &&) = delete; - C () = default; -}; - -// Note, P2786R13 says it is trivially relocatable, but I think -// it isn't default-movable because overload resolution in both -// cases selects a deleted special member fn. -static_assert (!std::is_trivially_relocatable_v <C>, ""); -static_assert (!std::is_replaceable_v <C>, ""); - -struct D : A {}; - -static_assert (std::is_trivially_relocatable_v <D>, ""); -static_assert (std::is_replaceable_v <D>, ""); - -struct E : virtual A {}; - -static_assert (!std::is_trivially_relocatable_v <E>, ""); -static_assert (std::is_replaceable_v <E>, ""); - -struct F trivially_relocatable_if_eligible : virtual A {}; - -static_assert (!std::is_trivially_relocatable_v <F>, ""); -static_assert (std::is_replaceable_v <F>, ""); - -struct G { B data; }; - -static_assert (!std::is_trivially_relocatable_v <G>, ""); -static_assert (!std::is_replaceable_v <G>, ""); - -struct H { ~H () = default; }; - -static_assert (std::is_trivially_relocatable_v <H>, ""); -static_assert (std::is_replaceable_v <H>, ""); - -struct I { ~I (); }; -I::~I () = default; - -static_assert (!std::is_trivially_relocatable_v <I>, ""); -static_assert (!std::is_replaceable_v <I>, ""); - -struct J { virtual ~J () = default; }; - -// Note, P2786R13 says otherwise for both, but that looks like -// a bug in the paper, it otherwise says that polymorphic types -// can be both trivially relocatable and replaceable. -static_assert (std::is_trivially_relocatable_v <J>, ""); -static_assert (std::is_replaceable_v <J>, ""); - -struct K { ~K () = delete; }; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (!std::is_replaceable_v <K>, ""); - -struct L { L (L &&) = default; }; - -// Note, P2786R13 says otherwise for both, but that looks like -// a bug in the paper to me. While move ctor is trivial here, -// copy assignment operator is implicitly declared as deleted -// and move assignent operator is not declared. -static_assert (!std::is_trivially_relocatable_v <L>, ""); -static_assert (!std::is_replaceable_v <L>, ""); - -struct M { M (M &&); }; -M::M (M &&) = default; - -static_assert (!std::is_trivially_relocatable_v <M>, ""); -static_assert (!std::is_replaceable_v <M>, ""); - -struct N { N (N &&) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <N>, ""); -static_assert (!std::is_replaceable_v <N>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable2.C.jj 2025-07-11 19:01:25.979530617 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable2.C 2025-11-08 10:13:00.443596477 +0100 @@ -1,204 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -class A {}; - -static_assert (std::is_trivially_relocatable_v <A>, ""); -static_assert (std::is_replaceable_v <A>, ""); -static_assert (std::is_trivially_relocatable <A>::value, ""); -static_assert (std::is_replaceable <A>::value, ""); - -struct B { ~B (); }; -static B z; - -static_assert (!std::is_trivially_relocatable_v <B>, ""); -static_assert (!std::is_replaceable_v <B>, ""); -static_assert (!std::is_trivially_relocatable <B>::value, ""); -static_assert (!std::is_replaceable <B>::value, ""); - -class C trivially_relocatable_if_eligible {}; - -static_assert (std::is_trivially_relocatable_v <C>, ""); -static_assert (std::is_replaceable_v <C>, ""); - -class D trivially_relocatable_if_eligible : A {}; - -static_assert (std::is_trivially_relocatable_v <D>, ""); -static_assert (std::is_replaceable_v <D>, ""); - -class E trivially_relocatable_if_eligible { - int a; - void *b; - int c[3]; - A d[3]; - B &e = z; -}; - -static_assert (std::is_trivially_relocatable_v <E>, ""); -static_assert (!std::is_replaceable_v <E>, ""); - -class F trivially_relocatable_if_eligible : A {}; - -static_assert (std::is_trivially_relocatable_v <F>, ""); -static_assert (std::is_replaceable_v <F>, ""); - -class G trivially_relocatable_if_eligible : virtual A {}; - -static_assert (!std::is_trivially_relocatable_v <G>, ""); -static_assert (std::is_replaceable_v <G>, ""); - -class H trivially_relocatable_if_eligible : B {}; - -static_assert (!std::is_trivially_relocatable_v <H>, ""); -static_assert (!std::is_replaceable_v <H>, ""); - -class I trivially_relocatable_if_eligible { I (I &&); }; - -static_assert (std::is_trivially_relocatable_v <I>, ""); -static_assert (!std::is_replaceable_v <I>, ""); - -class J trivially_relocatable_if_eligible { ~J (); }; - -static_assert (std::is_trivially_relocatable_v <J>, ""); -static_assert (!std::is_replaceable_v <J>, ""); - -class K trivially_relocatable_if_eligible { - B a; - B b[1]; - const B c; - const B d[1]; -}; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (!std::is_replaceable_v <K>, ""); - -class L trivially_relocatable_if_eligible: virtual A, B { B a; }; - -static_assert (!std::is_trivially_relocatable_v <L>, ""); -static_assert (!std::is_replaceable_v <L>, ""); - -static_assert (!std::is_trivially_relocatable_v <void>, ""); -static_assert (!std::is_trivially_relocatable_v <const void>, ""); -static_assert (std::is_trivially_relocatable_v <int>, ""); -static_assert (std::is_trivially_relocatable_v <const int>, ""); -static_assert (std::is_trivially_relocatable_v <char>, ""); -static_assert (std::is_trivially_relocatable_v <char const volatile>, ""); -static_assert (std::is_trivially_relocatable_v <unsigned long long>, ""); -static_assert (std::is_trivially_relocatable_v <void *>, ""); -static_assert (std::is_trivially_relocatable_v <const int *>, ""); -static_assert (!std::is_trivially_relocatable_v <int &>, ""); -static_assert (!std::is_trivially_relocatable_v <A &>, ""); -static_assert (std::is_trivially_relocatable_v <const A>, ""); -static_assert (std::is_trivially_relocatable_v <A [1]>, ""); -static_assert (std::is_trivially_relocatable_v <A []>, ""); -static_assert (!std::is_replaceable_v <void>, ""); -static_assert (!std::is_replaceable_v <const void>, ""); -static_assert (std::is_replaceable_v <int>, ""); -static_assert (!std::is_replaceable_v <const int>, ""); -static_assert (std::is_replaceable_v <char>, ""); -static_assert (!std::is_replaceable_v <char const volatile>, ""); -static_assert (std::is_replaceable_v <unsigned long long>, ""); -static_assert (std::is_replaceable_v <void *>, ""); -static_assert (std::is_replaceable_v <const int *>, ""); -static_assert (!std::is_replaceable_v <int &>, ""); -static_assert (!std::is_replaceable_v <A &>, ""); -static_assert (!std::is_replaceable_v <const A>, ""); -static_assert (std::is_replaceable_v <A [1]>, ""); -static_assert (std::is_replaceable_v <A []>, ""); - -struct M { const int i; }; - -static_assert (!std::is_trivially_relocatable_v <M>, ""); -static_assert (!std::is_replaceable_v <M>, ""); - -struct N trivially_relocatable_if_eligible { const int i; }; - -static_assert (std::is_trivially_relocatable_v <N>, ""); -static_assert (!std::is_replaceable_v <N>, ""); - -struct O { ~O (); }; - -static_assert (!std::is_trivially_relocatable_v <O>, ""); -static_assert (!std::is_replaceable_v <O>, ""); - -struct P { ~P () = default; }; - -static_assert (std::is_trivially_relocatable_v <P>, ""); -static_assert (std::is_replaceable_v <P>, ""); - -struct Q { Q (Q &&); Q (const Q &) = default; }; - -static_assert (!std::is_trivially_relocatable_v <Q>, ""); -static_assert (!std::is_replaceable_v <Q>, ""); - -struct R { R (R &&); }; - -static_assert (!std::is_trivially_relocatable_v <R>, ""); -static_assert (!std::is_replaceable_v <R>, ""); - -struct S { S (S &&) = default; }; - -static_assert (!std::is_trivially_relocatable_v <S>, ""); -static_assert (!std::is_replaceable_v <S>, ""); - -struct T { T (T &&) = default; T &operator= (T &&) = default; }; - -static_assert (std::is_trivially_relocatable_v <T>, ""); -static_assert (std::is_replaceable_v <T>, ""); - -struct U { U (const U &); }; - -static_assert (!std::is_trivially_relocatable_v <U>, ""); -static_assert (!std::is_replaceable_v <U>, ""); - -struct V { V (const V&) = default; }; - -static_assert (std::is_trivially_relocatable_v <V>, ""); -static_assert (std::is_replaceable_v <V>, ""); - -struct W { W (W &&) = delete; W (const W &) = default; }; - -static_assert (!std::is_trivially_relocatable_v <W>, ""); -static_assert (!std::is_replaceable_v <W>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable3.C.jj 2025-07-11 19:01:25.979530617 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable3.C 2025-11-08 10:13:00.522595350 +0100 @@ -1,213 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -class A {}; - -struct B { ~B (); }; - -class C trivially_relocatable_if_eligible { C (C &&); }; - -template <typename T> -class D trivially_relocatable_if_eligible : T {}; -D<A> a; -D<B> b; - -static_assert (std::is_trivially_relocatable_v <D<A>>, ""); -static_assert (!std::is_trivially_relocatable_v <D<B>>, ""); -static_assert (std::is_replaceable_v <D<A>>, ""); -static_assert (!std::is_replaceable_v <D<B>>, ""); - -struct E { E (E &&) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <E>, ""); -static_assert (!std::is_replaceable_v <E>, ""); - -struct F { F (const F &) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <F>, ""); -static_assert (!std::is_replaceable_v <F>, ""); - -struct G { G &operator= (G &&) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <G>, ""); -static_assert (!std::is_replaceable_v <G>, ""); - -struct H { ~H () = delete; }; - -static_assert (!std::is_trivially_relocatable_v <H>, ""); -static_assert (!std::is_replaceable_v <H>, ""); - -union U { C u; }; - -static_assert (std::is_trivially_relocatable_v <U>, ""); -static_assert (!std::is_replaceable_v <U>, ""); - -template <typename T> -struct I { int s; T t; }; - -static_assert (std::is_trivially_relocatable_v <I<int>>, ""); -static_assert (std::is_trivially_relocatable_v <I<volatile int>>, ""); -static_assert (!std::is_trivially_relocatable_v <I<const int>>, ""); -static_assert (!std::is_trivially_relocatable_v <I<const int &>>, ""); -static_assert (!std::is_trivially_relocatable_v <I<int &>>, ""); -static_assert (std::is_trivially_relocatable_v <I<int [2]>>, ""); -static_assert (!std::is_trivially_relocatable_v <I<const int [2]>>, ""); -static_assert (std::is_trivially_relocatable_v <I<int []>>, ""); -static_assert (std::is_replaceable_v <I<int>>, ""); -static_assert (!std::is_replaceable_v <I<volatile int>>, ""); -static_assert (!std::is_replaceable_v <I<const int>>, ""); -static_assert (!std::is_replaceable_v <I<const int &>>, ""); -static_assert (!std::is_replaceable_v <I<int &>>, ""); -static_assert (std::is_replaceable_v <I<int [2]>>, ""); -static_assert (!std::is_replaceable_v <I<const int [2]>>, ""); - -template <typename T> -struct J trivially_relocatable_if_eligible { int s; T t; }; - -static_assert (std::is_trivially_relocatable_v <J<int>>, ""); -static_assert (std::is_trivially_relocatable_v <J<volatile int>>, ""); -static_assert (std::is_trivially_relocatable_v <J<const int>>, ""); -static_assert (std::is_trivially_relocatable_v <J<const int &>>, ""); -static_assert (std::is_trivially_relocatable_v <J<int &>>, ""); -static_assert (std::is_trivially_relocatable_v <J<int [2]>>, ""); -static_assert (std::is_trivially_relocatable_v <J<const int [2]>>, ""); -static_assert (std::is_trivially_relocatable_v <J<int []>>, ""); -static_assert (std::is_replaceable_v <J<int>>, ""); -static_assert (!std::is_replaceable_v <J<volatile int>>, ""); -static_assert (!std::is_replaceable_v <J<const int>>, ""); -static_assert (!std::is_replaceable_v <J<const int &>>, ""); -static_assert (!std::is_replaceable_v <J<int &>>, ""); -static_assert (std::is_replaceable_v <J<int [2]>>, ""); -static_assert (!std::is_replaceable_v <J<const int [2]>>, ""); -static_assert (std::is_replaceable_v <J<int []>>, ""); - -struct K { K (K &&) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (!std::is_replaceable_v <K>, ""); - -struct L { L (const L &) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <L>, ""); -static_assert (!std::is_replaceable_v <L>, ""); - -struct M { M &operator= (M &&) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <M>, ""); -static_assert (!std::is_replaceable_v <M>, ""); - -struct N { N (N &&) = default; N &operator= (N &&) = default; }; - -static_assert (std::is_trivially_relocatable_v <N>, ""); -static_assert (std::is_replaceable_v <N>, ""); - -struct O { - O (const O &) = default; - O (O &&) = default; - O &operator= (O &&) = default; -}; - -static_assert (std::is_trivially_relocatable_v <O>, ""); -static_assert (std::is_replaceable_v <O>, ""); - -struct P { P (P &&) = default; P &operator= (P &&) = default; }; - -static_assert (std::is_trivially_relocatable_v <P>, ""); -static_assert (std::is_replaceable_v <P>, ""); - -struct Q { Q (Q &&) {} }; - -static_assert (!std::is_trivially_relocatable_v <Q>, ""); -static_assert (!std::is_replaceable_v <Q>, ""); - -struct R { R (const R &) {} }; - -static_assert (!std::is_trivially_relocatable_v <R>, ""); -static_assert (!std::is_replaceable_v <R>, ""); - -struct S { S &operator= (const S &) { return *this; }; }; - -static_assert (!std::is_trivially_relocatable_v <S>, ""); -static_assert (!std::is_replaceable_v <S>, ""); - -struct T {}; - -static_assert (std::is_trivially_relocatable_v <T>, ""); -static_assert (std::is_replaceable_v <T>, ""); - -struct V replaceable_if_eligible {}; - -static_assert (std::is_trivially_relocatable_v <V>, ""); -static_assert (std::is_replaceable_v <V>, ""); - -struct W { template <typename U> W (const U &) = delete; }; - -static_assert (std::is_trivially_relocatable_v <W>, ""); -static_assert (std::is_replaceable_v <W>, ""); - -template <typename T> -struct X : T {}; - -static_assert (!std::is_trivially_relocatable_v <X<Q>>, ""); -static_assert (!std::is_replaceable_v <X<Q>>, ""); - -template <typename T> -struct Y : virtual T {}; - -static_assert (!std::is_trivially_relocatable_v <Y<I<int>>>, ""); -static_assert (!std::is_trivially_relocatable_v <Y<I<const int>>>, ""); -static_assert (!std::is_trivially_relocatable_v <Y<Q>>, ""); -static_assert (std::is_replaceable_v <Y<I<int>>>, ""); -static_assert (!std::is_replaceable_v <Y<I<const int>>>, ""); -static_assert (!std::is_replaceable_v <Y<Q>>, ""); - -struct Z { - virtual ~Z () = default; - Z (Z &&) = default; - Z &operator= (Z &&) = default; -}; - -static_assert (std::is_trivially_relocatable_v <Z>, ""); -static_assert (std::is_replaceable_v <Z>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable4.C.jj 2025-07-11 19:01:25.979530617 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable4.C 2025-11-08 10:13:00.485595878 +0100 @@ -1,128 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -struct A replaceable_if_eligible { - ~A () = delete; - A (A &&) = default; - A &operator= (A &&) = default; -}; - -static_assert (!std::is_trivially_relocatable_v <A>, ""); -static_assert (!std::is_replaceable_v <A>, ""); - -struct B replaceable_if_eligible { B (const B &) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <B>, ""); -static_assert (!std::is_replaceable_v <B>, ""); - -template <typename T> -struct C replaceable_if_eligible : virtual T {}; - -static_assert (!std::is_trivially_relocatable_v <C<A>>, ""); -static_assert (!std::is_trivially_relocatable_v <C<B>>, ""); -static_assert (!std::is_replaceable_v <C<A>>, ""); -static_assert (!std::is_replaceable_v <C<B>>, ""); - -template <typename T> -struct D { int s; T t; }; - -static_assert (!std::is_trivially_relocatable_v <C<D<int>>>, ""); -static_assert (std::is_replaceable_v <C<D<int>>>, ""); - -struct E trivially_relocatable_if_eligible replaceable_if_eligible { - E (E &&); - E &operator= (E &&) = default; -}; - -static_assert (std::is_trivially_relocatable_v <E>, ""); -static_assert (std::is_replaceable_v <E>, ""); - -struct F trivially_relocatable_if_eligible replaceable_if_eligible { - F (F &&) = default; - F &operator= (F &&); -}; - -static_assert (std::is_trivially_relocatable_v <F>, ""); -static_assert (std::is_replaceable_v <F>, ""); - -struct G replaceable_if_eligible { G (G const &) = default; }; - -static_assert (std::is_trivially_relocatable_v <G>, ""); -static_assert (std::is_replaceable_v <G>, ""); - -struct H { H (H const &) = default; }; - -static_assert (std::is_trivially_relocatable_v <H>, ""); -static_assert (std::is_replaceable_v <H>, ""); - -struct I replaceable_if_eligible { I &operator= (const I &) = default; }; - -static_assert (std::is_trivially_relocatable_v <I>, ""); -static_assert (std::is_replaceable_v <I>, ""); - -struct J { J &operator= (J const &) = default; }; - -static_assert (std::is_trivially_relocatable_v <J>, ""); -static_assert (std::is_replaceable_v <J>, ""); - -struct K { K (const K &) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (!std::is_replaceable_v <K>, ""); - -struct L { L (L&&) = delete; }; - -static_assert (!std::is_trivially_relocatable_v <L>, ""); -static_assert (!std::is_replaceable_v <L>, ""); - -struct M { M operator= (M); }; - -static_assert (!std::is_trivially_relocatable_v <M>, ""); -static_assert (!std::is_replaceable_v <M>, ""); - -struct N { N operator= (N &&); }; - -static_assert (!std::is_trivially_relocatable_v <N>, ""); -static_assert (!std::is_replaceable_v <N>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable5.C.jj 2025-07-11 19:01:25.980530604 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable5.C 2025-11-08 10:13:00.497595707 +0100 @@ -1,77 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-additional-options "-Wc++26-compat" } - -struct A __trivially_relocatable_if_eligible { A (const A &&); }; -struct B __replaceable_if_eligible { B (const B &&); B &operator= (B &&); }; -struct C __replaceable_if_eligible __final __trivially_relocatable_if_eligible { C (const C &&); C &operator= (C &&); }; -#if __cpp_trivial_relocatability >= 202502L -struct D trivially_relocatable_if_eligible { D (const D &&); }; -struct E replaceable_if_eligible { E (const E &&); E &operator= (E &&); }; -struct F trivially_relocatable_if_eligible replaceable_if_eligible final { F (const F &&); F &operator= (F &&); }; -#else -struct D trivially_relocatable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -// { dg-error "variable 'D trivially_relocatable_if_eligible' has initializer but incomplete type" "" { target c++23_down } .-1 } -struct E replaceable_if_eligible {}; // { dg-warning "identifier 'replaceable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -// { dg-error "variable 'E replaceable_if_eligible' has initializer but incomplete type" "" { target c++23_down } .-1 } -struct F trivially_relocatable_if_eligible replaceable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -// { dg-error "expected initializer before 'replaceable_if_eligible'" "" { target c++23_down } .-1 } -#endif -#if __cplusplus <= 202302L -struct G {}; -struct G trivially_relocatable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -struct H {}; -struct H replaceable_if_eligible {}; // { dg-warning "identifier 'replaceable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -struct I {}; -struct I trivially_relocatable_if_eligible replaceable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -#endif // { dg-error "expected initializer before 'replaceable_if_eligible'" "" { target c++23_down } .-1 } -struct J {}; -struct J __trivially_relocatable_if_eligible {}; // { dg-error "redefinition of 'struct J'" } -struct K {}; -struct K __replaceable_if_eligible {}; // { dg-error "redefinition of 'struct K'" } -struct L {}; -struct L __trivially_relocatable_if_eligible __replaceable_if_eligible {}; // { dg-error "redefinition of 'struct L'" } -struct M __trivially_relocatable_if_eligible __trivially_relocatable_if_eligible {}; // { dg-error "duplicate '__trivially_relocatable_if_eligible' specifier" } -struct N __replaceable_if_eligible __replaceable_if_eligible {}; // { dg-error "duplicate '__replaceable_if_eligible' specifier" } -struct O __trivially_relocatable_if_eligible __replaceable_if_eligible __replaceable_if_eligible __trivially_relocatable_if_eligible final final {}; -// { dg-error "duplicate '__replaceable_if_eligible' specifier" "" { target *-*-* } .-1 } -// { dg-error "duplicate '__trivially_relocatable_if_eligible' specifier" "" { target *-*-* } .-2 } -// { dg-error "duplicate 'final' specifier" "" { target *-*-* } .-3 } -#if __cpp_trivial_relocatability >= 202502L -struct P trivially_relocatable_if_eligible trivially_relocatable_if_eligible {}; // { dg-error "duplicate 'trivially_relocatable_if_eligible' specifier" "" { target c++26 } } -struct Q replaceable_if_eligible replaceable_if_eligible {}; // { dg-error "duplicate 'replaceable_if_eligible' specifier" "" { target c++26 } } -struct R trivially_relocatable_if_eligible replaceable_if_eligible replaceable_if_eligible trivially_relocatable_if_eligible final final {}; -// { dg-error "duplicate 'replaceable_if_eligible' specifier" "" { target c++26 } .-1 } -// { dg-error "duplicate 'trivially_relocatable_if_eligible' specifier" "" { target c++26 } .-2 } -// { dg-error "duplicate 'final' specifier" "" { target c++26 } .-3 } -struct S trivially_relocatable_if_eligible __trivially_relocatable_if_eligible {}; // { dg-error "duplicate '__trivially_relocatable_if_eligible' specifier" "" { target c++26 } } -struct T replaceable_if_eligible __replaceable_if_eligible {}; // { dg-error "duplicate '__replaceable_if_eligible' specifier" "" { target c++26 } } -struct U trivially_relocatable_if_eligible replaceable_if_eligible __replaceable_if_eligible __trivially_relocatable_if_eligible final __final {}; -// { dg-error "duplicate '__replaceable_if_eligible' specifier" "" { target c++26 } .-1 } -// { dg-error "duplicate '__trivially_relocatable_if_eligible' specifier" "" { target c++26 } .-2 } -// { dg-error "duplicate '__final' specifier" "" { target c++26 } .-3 } -struct V __trivially_relocatable_if_eligible trivially_relocatable_if_eligible {}; // { dg-error "duplicate 'trivially_relocatable_if_eligible' specifier" "" { target c++26 } } -struct W __replaceable_if_eligible replaceable_if_eligible {}; // { dg-error "duplicate 'replaceable_if_eligible' specifier" "" { target c++26 } } -struct X __trivially_relocatable_if_eligible __replaceable_if_eligible replaceable_if_eligible trivially_relocatable_if_eligible __final final {}; -// { dg-error "duplicate 'replaceable_if_eligible' specifier" "" { target c++26 } .-1 } -// { dg-error "duplicate 'trivially_relocatable_if_eligible' specifier" "" { target c++26 } .-2 } -// { dg-error "duplicate 'final' specifier" "" { target c++26 } .-3 } -#else -struct Y {}; -Y foo (); -struct Y trivially_relocatable_if_eligible = foo (); // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -struct Z {}; -Z bar (); -struct Z replaceable_if_eligible = bar (); // { dg-warning "identifier 'replaceable_if_eligible' is a conditional keyword in" "" { target c++23_down } } -#endif - -static_assert (__builtin_is_trivially_relocatable (A), ""); -static_assert (__builtin_is_replaceable (B), ""); -static_assert (__builtin_is_trivially_relocatable (C), ""); -static_assert (__builtin_is_replaceable (C), ""); -#if __cpp_trivial_relocatability >= 202502L -static_assert (__builtin_is_trivially_relocatable (D), ""); -static_assert (__builtin_is_replaceable (E), ""); -static_assert (__builtin_is_trivially_relocatable (F), ""); -static_assert (__builtin_is_replaceable (F), ""); -#endif --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable6.C.jj 2025-07-11 19:01:25.980530604 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable6.C 2025-11-08 10:13:00.540595093 +0100 @@ -1,30 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++98_only } } -// { dg-additional-options "-Wc++26-compat" } - -struct A __trivially_relocatable_if_eligible {}; -struct B __replaceable_if_eligible {}; -struct C __replaceable_if_eligible __final __trivially_relocatable_if_eligible {}; -struct D trivially_relocatable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" } -// { dg-error "variable 'D trivially_relocatable_if_eligible' has initializer but incomplete type" "" { target *-*-* } .-1 } -// { dg-error "extended initializer lists only available with" "" { target *-*-* } .-2 } -struct E replaceable_if_eligible {}; // { dg-warning "identifier 'replaceable_if_eligible' is a conditional keyword in" } -// { dg-error "variable 'E replaceable_if_eligible' has initializer but incomplete type" "" { target *-*-* } .-1 } -// { dg-error "extended initializer lists only available with" "" { target *-*-* } .-2 } -struct F trivially_relocatable_if_eligible replaceable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" } -// { dg-error "expected initializer before 'replaceable_if_eligible'" "" { target *-*-* } .-1 } -struct G {}; -struct G trivially_relocatable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" } -// { dg-error "extended initializer lists only available with" "" { target *-*-* } .-1 } -struct H {}; -struct H replaceable_if_eligible {}; // { dg-warning "identifier 'replaceable_if_eligible' is a conditional keyword in" } -// { dg-error "extended initializer lists only available with" "" { target *-*-* } .-1 } -struct I {}; -struct I trivially_relocatable_if_eligible replaceable_if_eligible {}; // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" } -// { dg-error "expected initializer before 'replaceable_if_eligible'" "" { target *-*-* } .-1 } -struct J {}; -J foo (); -struct J trivially_relocatable_if_eligible = foo (); // { dg-warning "identifier 'trivially_relocatable_if_eligible' is a conditional keyword in" } -struct K {}; -K bar (); -struct K replaceable_if_eligible = bar (); // { dg-warning "identifier 'replaceable_if_eligible' is a conditional keyword in" } --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable7.C.jj 2025-07-11 19:01:25.980530604 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable7.C 2025-11-08 10:13:00.544595036 +0100 @@ -1,33 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - // { dg-error "invalid use of incomplete type 'struct A'" "" { target *-*-* } .-1 } - -template <typename T> -inline constexpr bool is_nothrow_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_nothrow_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - // { dg-error "invalid use of incomplete type 'struct A'" "" { target *-*-* } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} // { dg-error "invalid use of incomplete type 'struct A'" "" { target *-*-* } .-1 } - -struct A; // { dg-message "forward declaration of 'struct A'" } - -auto a = std::is_trivially_relocatable_v <A>; // { dg-message "required from here" } -auto b = std::is_nothrow_relocatable_v <A>; // { dg-message "required from here" } -auto c = std::is_replaceable_v <A>; // { dg-message "required from here" } --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable8.C.jj 2025-07-11 19:01:25.980530604 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable8.C 2025-11-08 10:13:00.546595007 +0100 @@ -1,190 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_nothrow_relocatable - : public integral_constant <bool, __builtin_is_nothrow_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_nothrow_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_nothrow_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -struct A { A (A &&) = default; A &operator= (A &&) = default; ~A () = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <A>, ""); -static_assert (std::is_nothrow_relocatable_v <A>, ""); -static_assert (std::is_replaceable_v <A>, ""); - -struct B { B (B &&); B &operator= (B &&) = default; ~B () = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <B>, ""); -static_assert (!std::is_nothrow_relocatable_v <B>, ""); -static_assert (!std::is_replaceable_v <B>, ""); - -struct C { C (C &&) = default; C &operator= (C &&); ~C () = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <C>, ""); -static_assert (std::is_nothrow_relocatable_v <C>, ""); -static_assert (!std::is_replaceable_v <C>, ""); - -struct D { D (D &&) = delete; D &operator= (D &&) = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <D>, ""); -static_assert (!std::is_nothrow_relocatable_v <D>, ""); -static_assert (!std::is_replaceable_v <D>, ""); - -struct E { E (E &&) = default; E &operator= (E &&) = delete; int a; }; - -static_assert (!std::is_trivially_relocatable_v <E>, ""); -static_assert (std::is_nothrow_relocatable_v <E>, ""); -static_assert (!std::is_replaceable_v <E>, ""); - -struct F { F (F &&) = default; F &operator= (F &&) = default; ~F () = delete; int a; }; - -static_assert (!std::is_trivially_relocatable_v <F>, ""); -static_assert (!std::is_nothrow_relocatable_v <F>, ""); -static_assert (!std::is_replaceable_v <F>, ""); - -struct G { G (const G &) = default; G &operator= (const G &) = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <G>, ""); -static_assert (std::is_nothrow_relocatable_v <G>, ""); -static_assert (std::is_replaceable_v <G>, ""); - -struct H { H (const H &); H &operator= (const H &) = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <H>, ""); -static_assert (!std::is_nothrow_relocatable_v <H>, ""); -static_assert (!std::is_replaceable_v <H>, ""); - -struct I { I (const I &) = default; I &operator= (const I &); ~I () = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <I>, ""); -static_assert (std::is_nothrow_relocatable_v <I>, ""); -static_assert (!std::is_replaceable_v <I>, ""); - -struct J { J (const J &) = delete; J &operator= (const J &) = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <J>, ""); -static_assert (!std::is_nothrow_relocatable_v <J>, ""); -static_assert (!std::is_replaceable_v <J>, ""); - -struct K { K (const K &) = default; K &operator= (const K &) = delete; int a; }; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (std::is_nothrow_relocatable_v <K>, ""); -static_assert (!std::is_replaceable_v <K>, ""); - -struct M; -struct L { L (L &&) = default; L (M &&); L &operator= (L &&) = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <L>, ""); -static_assert (std::is_nothrow_relocatable_v <L>, ""); -static_assert (std::is_replaceable_v <L>, ""); - -struct M : public L { using L::L; M (const M &); M &operator= (M &&) = default; int b; }; - -static_assert (!std::is_trivially_relocatable_v <M>, ""); -static_assert (!std::is_nothrow_relocatable_v <M>, ""); -static_assert (!std::is_replaceable_v <M>, ""); - -struct O; -struct N { N (N &&) = default; N &operator= (N &&) = default; N &operator= (O &&); int a; }; - -static_assert (std::is_trivially_relocatable_v <N>, ""); -static_assert (std::is_nothrow_relocatable_v <N>, ""); -static_assert (std::is_replaceable_v <N>, ""); - -struct O : public N { using N::operator=; O (O &&) = default; int b; }; - -static_assert (!std::is_trivially_relocatable_v <O>, ""); -static_assert (std::is_nothrow_relocatable_v <O>, ""); -static_assert (!std::is_replaceable_v <O>, ""); - -struct Q; -struct P { template <typename T> P (T &&) {} }; - -static_assert (std::is_trivially_relocatable_v <P>, ""); -static_assert (std::is_nothrow_relocatable_v <P>, ""); -static_assert (std::is_replaceable_v <P>, ""); - -struct Q : public P { using P::P; Q (const Q &); }; - -static_assert (!std::is_trivially_relocatable_v <Q>, ""); -static_assert (!std::is_nothrow_relocatable_v <Q>, ""); -static_assert (!std::is_replaceable_v <Q>, ""); - -struct S; -struct R { R (const R &) = default; R (const M &); R &operator= (R &&) = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <R>, ""); -static_assert (std::is_nothrow_relocatable_v <R>, ""); -static_assert (std::is_replaceable_v <R>, ""); - -struct S : public R { using R::R; S &operator= (S &&) = default; int b; }; - -static_assert (!std::is_trivially_relocatable_v <S>, ""); -static_assert (!std::is_nothrow_relocatable_v <S>, ""); -static_assert (!std::is_replaceable_v <S>, ""); - -struct T { T (T &&) = default; T &operator= (T &&) = default; ~T (); int a; }; - -static_assert (!std::is_trivially_relocatable_v <T>, ""); -static_assert (std::is_nothrow_relocatable_v <T>, ""); -static_assert (!std::is_replaceable_v <T>, ""); - -struct U { U (const U &) = default; U &operator= (const U &) = default; ~U (); int a; }; - -static_assert (!std::is_trivially_relocatable_v <U>, ""); -static_assert (std::is_nothrow_relocatable_v <U>, ""); -static_assert (!std::is_replaceable_v <U>, ""); - -struct V { public: V (); private: V (V &&) = default; V &operator= (V &&) = default; ~V () = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <V>, ""); -static_assert (std::is_nothrow_relocatable_v <V>, ""); -static_assert (std::is_replaceable_v <V>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable9.C.jj 2025-07-11 19:01:25.981530591 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable9.C 2025-11-08 10:13:00.549594965 +0100 @@ -1,134 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_nothrow_relocatable - : public integral_constant <bool, __builtin_is_nothrow_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_nothrow_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_nothrow_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -struct A trivially_relocatable_if_eligible { A (A &&); A &operator= (A &&); ~A (); int a; }; - -static_assert (std::is_trivially_relocatable_v <A>, ""); -static_assert (std::is_nothrow_relocatable_v <A>, ""); - -struct B { B (B &&); B &operator= (B &&); ~B (); int a; }; - -static_assert (!std::is_trivially_relocatable_v <B>, ""); -static_assert (!std::is_nothrow_relocatable_v <B>, ""); - -struct C trivially_relocatable_if_eligible : public A { C (C &&); C &operator= (C &&); ~C (); int a; }; - -static_assert (std::is_trivially_relocatable_v <C>, ""); -static_assert (std::is_nothrow_relocatable_v <C>, ""); - -struct D trivially_relocatable_if_eligible : public B { D (D &&); D &operator= (D &&); ~D (); int a; }; - -static_assert (!std::is_trivially_relocatable_v <D>, ""); -static_assert (!std::is_nothrow_relocatable_v <D>, ""); - -struct E trivially_relocatable_if_eligible { E (E &&); E &operator= (E &&); ~E (); A a; }; - -static_assert (std::is_trivially_relocatable_v <E>, ""); -static_assert (std::is_nothrow_relocatable_v <E>, ""); - -struct F trivially_relocatable_if_eligible { F (F &&) noexcept; F &operator= (F &&); ~F (); B a; }; - -static_assert (!std::is_trivially_relocatable_v <F>, ""); -static_assert (std::is_nothrow_relocatable_v <F>, ""); - -struct G trivially_relocatable_if_eligible { G (G &&); G &operator= (G &&); ~G () = delete; int a; }; - -static_assert (!std::is_trivially_relocatable_v <G>, ""); -static_assert (!std::is_nothrow_relocatable_v <G>, ""); - -struct H trivially_relocatable_if_eligible : virtual A { H (H &&); H &operator= (H &&); ~H (); int a; }; - -static_assert (!std::is_trivially_relocatable_v <H>, ""); -static_assert (!std::is_nothrow_relocatable_v <H>, ""); - -struct I trivially_relocatable_if_eligible { I (I &&); I &operator= (I &&); ~I (); A &a; int &b; }; - -static_assert (std::is_trivially_relocatable_v <I>, ""); -static_assert (std::is_nothrow_relocatable_v <I>, ""); - -struct J trivially_relocatable_if_eligible { J (J &&); J &operator= (J &&); ~J (); B &a; int &b; }; - -static_assert (std::is_trivially_relocatable_v <J>, ""); -static_assert (std::is_nothrow_relocatable_v <J>, ""); - -struct K trivially_relocatable_if_eligible { K (K &&) noexcept; K &operator= (K &&); ~K (); union { A a; int b; char c; }; }; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (std::is_nothrow_relocatable_v <K>, ""); - -struct L trivially_relocatable_if_eligible { L (L &&); L &operator= (L &&); ~L (); union { int a; B b; short c; }; }; - -static_assert (!std::is_trivially_relocatable_v <L>, ""); -static_assert (!std::is_nothrow_relocatable_v <L>, ""); - -struct M trivially_relocatable_if_eligible { M (M &&); M &operator= (M &&); ~M () = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <M>, ""); -static_assert (std::is_nothrow_relocatable_v <M>, ""); - -struct N trivially_relocatable_if_eligible { N (N &&); N &operator= (N &&); ~N (); union { M a; int b; char c; }; }; - -static_assert (std::is_trivially_relocatable_v <N>, ""); -static_assert (std::is_nothrow_relocatable_v <N>, ""); - -struct O trivially_relocatable_if_eligible { O (O &&); O &operator= (O &&); ~O (); union { unsigned long long a; int b; char c; }; }; - -static_assert (std::is_trivially_relocatable_v <O>, ""); -static_assert (std::is_nothrow_relocatable_v <O>, ""); - -struct P { P (P &&) noexcept; P &operator= (P &&); ~P (); int a; }; - -static_assert (!std::is_trivially_relocatable_v <P>, ""); -static_assert (std::is_nothrow_relocatable_v <P>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable10.C.jj 2025-07-11 19:01:25.981530591 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable10.C 2025-11-08 10:13:00.464596178 +0100 @@ -1,135 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -struct A replaceable_if_eligible { A (A &&); A &operator= (A &&); ~A (); int a; }; - -static_assert (std::is_replaceable_v <A>, ""); -static_assert (!std::is_replaceable_v <const A>, ""); -static_assert (!std::is_replaceable_v <A volatile>, ""); -static_assert (!std::is_replaceable_v <const A volatile>, ""); - -struct B { B (B &&); B &operator= (B &&); ~B (); int a; }; - -static_assert (!std::is_replaceable_v <B>, ""); - -struct C replaceable_if_eligible : public A { C (C &&); C &operator= (C &&); ~C (); int a; }; - -static_assert (std::is_replaceable_v <C>, ""); - -struct D replaceable_if_eligible : public B { D (D &&); D &operator= (D &&); ~D (); int a; }; - -static_assert (!std::is_replaceable_v <D>, ""); - -struct E replaceable_if_eligible { E (E &&); E &operator= (E &&); ~E (); A a; }; - -static_assert (std::is_replaceable_v <E>, ""); - -struct F replaceable_if_eligible { F (F &&); F &operator= (F &&); ~F (); B a; }; - -static_assert (!std::is_replaceable_v <F>, ""); - -struct G replaceable_if_eligible { G (G &&); G &operator= (G &&); ~G () = delete; int a; }; - -static_assert (!std::is_replaceable_v <G>, ""); - -struct H replaceable_if_eligible : virtual A { H (H &&); H &operator= (H &&); ~H (); int a; }; - -static_assert (std::is_replaceable_v <H>, ""); - -struct I replaceable_if_eligible { I (I &&) = delete; I &operator= (I &&); ~I (); int a; }; - -static_assert (!std::is_replaceable_v <I>, ""); - -struct J replaceable_if_eligible { J (J &&); J &operator= (J &&) = delete; ~J (); int a; }; - -static_assert (!std::is_replaceable_v <J>, ""); - -struct K replaceable_if_eligible { K (const K &) = delete; K &operator= (K &&); ~K (); int a; }; - -static_assert (!std::is_replaceable_v <K>, ""); - -struct L replaceable_if_eligible { L (L &&); L &operator= (const L &) = delete; ~L (); int a; }; - -static_assert (!std::is_replaceable_v <L>, ""); - -struct M replaceable_if_eligible { M (); private: M (M &&); M &operator= (M &&); ~M (); int a; }; - -static_assert (std::is_replaceable_v <M>, ""); - -struct N replaceable_if_eligible { N (N &&); N &operator= (N &&); ~N (); const A a; }; - -static_assert (!std::is_replaceable_v <N>, ""); - -struct O replaceable_if_eligible { O (O &&); O &operator= (O &&); ~O (); volatile A a; }; - -static_assert (!std::is_replaceable_v <O>, ""); - -struct P replaceable_if_eligible { P (P &&); P &operator= (P &&); ~P (); const volatile A a; }; - -static_assert (!std::is_replaceable_v <P>, ""); - -struct Q replaceable_if_eligible { Q (Q &&); Q &operator= (Q &&); ~Q (); union { A a; int b; char c; }; }; - -static_assert (!std::is_replaceable_v <Q>, ""); - -struct R replaceable_if_eligible { R (R &&); R &operator= (R &&); ~R (); union { int a; B b; short c; }; }; - -static_assert (!std::is_replaceable_v <R>, ""); - -struct S replaceable_if_eligible { S (S &&); S &operator= (S &&); ~S (); union { int a; const int b; short c; }; }; - -static_assert (!std::is_replaceable_v <S>, ""); - -struct T replaceable_if_eligible { T (T &&); T &operator= (T &&); ~T () = default; int a; }; - -static_assert (std::is_replaceable_v <T>, ""); - -struct U replaceable_if_eligible { U (U &&); U &operator= (U &&); ~U (); union { T a; int b; char c; }; }; - -static_assert (!std::is_replaceable_v <U>, ""); - -struct V replaceable_if_eligible { V (V &&); V &operator= (V &&); ~V (); union { unsigned long long a; int b; char c; }; }; - -static_assert (std::is_replaceable_v <V>, ""); --- gcc/testsuite/g++.dg/cpp26/trivially-relocatable11.C.jj 2025-07-11 19:01:25.981530591 +0200 +++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable11.C 2025-11-08 10:13:00.028602397 +0100 @@ -1,134 +0,0 @@ -// P2786R13 - C++26 Trivial Relocatability -// { dg-do compile { target c++11 } } -// { dg-options "" } -// { dg-additional-options "-pedantic" { target c++17 } } - -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -namespace std -{ -template <typename T, T v> -struct integral_constant -{ - static constexpr T value = v; -}; - -template <typename> -struct is_trivially_relocatable; - -template <typename> -struct is_replaceable; - -template<typename T> -struct is_trivially_relocatable - : public integral_constant <bool, __builtin_is_trivially_relocatable (T)> -{ -}; - -template<typename T> -struct is_replaceable - : public integral_constant <bool, __builtin_is_replaceable (T)> -{ -}; - -template <typename T> -inline constexpr bool is_trivially_relocatable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_trivially_relocatable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } - -template <typename T> -inline constexpr bool is_replaceable_v // { dg-warning "inline variables are only available with" "" { target c++14_down } } - = __builtin_is_replaceable (T); // { dg-warning "variable templates only available with" "" { target c++11_down } .-1 } -} - -struct A { A (A &&) = default; A &operator= (A &&) = default; ~A () = default; int a; }; - -static_assert (std::is_trivially_relocatable_v <A>, ""); -static_assert (std::is_replaceable_v <A>, ""); - -struct B { B (B &&); B &operator= (B &&) = default; ~B () = default; int a; }; - -static_assert (!std::is_trivially_relocatable_v <B>, ""); -static_assert (!std::is_replaceable_v <B>, ""); - -union C { int a; A b; }; - -static_assert (std::is_trivially_relocatable_v <C>, ""); -static_assert (std::is_replaceable_v <C>, ""); - -union D { int a; A b; B c; }; - -static_assert (!std::is_trivially_relocatable_v <D>, ""); -static_assert (!std::is_replaceable_v <D>, ""); - -union E { E (); int a; A b; }; - -static_assert (std::is_trivially_relocatable_v <E>, ""); -static_assert (std::is_replaceable_v <E>, ""); - -union F { F () = default; int a; A b; }; - -static_assert (std::is_trivially_relocatable_v <F>, ""); -static_assert (std::is_replaceable_v <F>, ""); - -union G { G (const G &); int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <G>, ""); -static_assert (!std::is_replaceable_v <G>, ""); - -union H { H (const H &) = default; int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <H>, ""); -static_assert (!std::is_replaceable_v <H>, ""); - -union I { I (I &&); int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <I>, ""); -static_assert (!std::is_replaceable_v <I>, ""); - -union J { J (J &&) = default; int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <J>, ""); -static_assert (!std::is_replaceable_v <J>, ""); - -union K { K &operator= (const K &); int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <K>, ""); -static_assert (!std::is_replaceable_v <K>, ""); - -union L { L &operator= (const L &) = default; int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <L>, ""); -static_assert (!std::is_replaceable_v <L>, ""); - -union M { M &operator= (M &&); int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <M>, ""); -static_assert (!std::is_replaceable_v <M>, ""); - -union N { N &operator= (N &&) = default; int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <N>, ""); -static_assert (!std::is_replaceable_v <N>, ""); - -union O { ~O (); int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <O>, ""); -static_assert (!std::is_replaceable_v <O>, ""); - -union P { ~P () = default; int a; A b; }; - -static_assert (!std::is_trivially_relocatable_v <P>, ""); -static_assert (!std::is_replaceable_v <P>, ""); - -union Q { int a; const A b; }; - -static_assert (std::is_trivially_relocatable_v <Q>, ""); -static_assert (!std::is_replaceable_v <Q>, ""); - -union S { volatile int a; A b; }; - -static_assert (std::is_trivially_relocatable_v <S>, ""); -static_assert (!std::is_replaceable_v <S>, ""); --- gcc/testsuite/g++.dg/modules/class-11_a.H.jj 2025-08-11 12:25:21.115994674 +0200 +++ gcc/testsuite/g++.dg/modules/class-11_a.H 2025-11-08 10:35:11.929610093 +0100 @@ -3,17 +3,6 @@ // { dg-module-cmi {} } // { dg-skip-if "test assumes that structs have padding" { default_packed } } -#if __cpp_trivial_relocatability < 202502L -#define trivially_relocatable_if_eligible __trivially_relocatable_if_eligible -#define replaceable_if_eligible __replaceable_if_eligible -#endif - -struct A trivially_relocatable_if_eligible { A(A&&); }; -struct B replaceable_if_eligible { B(B&&); B& operator=(B&&); }; -struct C {}; -static_assert(__builtin_is_trivially_relocatable(C) && __builtin_is_replaceable(C), ""); - - struct pr106381 { long l; char c = -1; --- gcc/testsuite/g++.dg/modules/class-11_b.C.jj 2025-08-11 12:25:21.116994661 +0200 +++ gcc/testsuite/g++.dg/modules/class-11_b.C 2025-11-08 10:34:45.239990340 +0100 @@ -3,10 +3,6 @@ import "class-11_a.H"; -static_assert(__builtin_is_trivially_relocatable(A), ""); -static_assert(__builtin_is_replaceable(B), ""); -static_assert(__builtin_is_trivially_relocatable(C) && __builtin_is_replaceable(C), ""); - struct M1 : pr106381 { char x; // { dg-warning "offset" "" { target c++14 } } }; Jakub
