Hi!

The following patch on top of
https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686210.html
https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686558.html
patches implements the compiler side of the C++26 paper.
Based on the https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119064#c3
feedback, the patch enables the new conditional keywords
trivially_relocatable_if_eligible and replaceable_if_eligible only
for C++26, for older versions those conditional keywords yield
-Wc++26-compat warning and are treated as normal identifiers.
Plus __trivially_relocatable_if_eligible and __replaceable_if_eligible
are handled as conditional keywords always without diagnostics (similarly
to __final in C++98).
The patch uses __builtin_ prefix on the new traits (but unlike clang
which for some weird reason chose to name one __builtin_is_replaceable
and another __builtin_is_cpp_trivially_relocatable this one uses
__builtin_is_replaceable and __builtin_is_trivially_relocatable.
I'll try to convince clang to change, they've only implemented it
recently.
The patch computes these properties on demand, only when something needs
them (at the expense of eating 2 more bits per lang_type, but I've recently
saved 64 bits and a patch to save another 64 bits is pending; and even
4 bits wouldn't fit).
The patch doesn't add __builtin_trivially_relocate builtin that clang has,
std::trivially_relocate is not constexpr and I think we don't need it for
now at least until we implement some kind of vtable pointer signing
__builtin_memmove should do the job.  Especially if libstdc++ will for clang
compatibility use the builtin if available and __builtin_memmove otherwise,
we can switch any time.
I've cross-tested all testcases also against the clang++ trunk
implementation, and both compilers agreed in everything except for
https://github.com/llvm/llvm-project/issues/143599
where clang++ was changed already and
https://github.com/llvm/llvm-project/issues/144232
where I believe clang++ got it wrong too.
The first testcase comes from
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2786r13.html#simple-worked-examples
just tweaked so that the classes are named differently each time and that it
compiles.  There are 3 differences from the paper vs. the g++ as well as
clang++ implementation, I've added comments into
trivially-relocatable1.C but I think either that part of the paper wasn't
updated through the later changes or it got it wrong.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-06-16  Jakub Jelinek  <ja...@redhat.com>

        PR c++/119064
gcc/
        * doc/invoke.texi (Wc++26-compat): Document.
gcc/c-family/
        * c.opt (Wc++26-compat): New option.
        * c.opt.urls: Regenerate.
        * c-opts.cc (c_common_post_options): Clear warn_cxx26_compat for
        C++26 or later.
        * c-cppbuiltin.cc (c_cpp_builtins): For C++26 predefine
        __cpp_trivial_relocatability=202502L.
gcc/cp/
        * cp-tree.h: Implement C++26 P2786R13 - Trivial Relocatability.
        (struct lang_type): Add trivially_relocatable_if_eligible,
        replaceable_if_eligible, trivially_relocatable,
        trivially_relocatable_computed, replaceable and replaceable_computed
        bitfields.  Change width of dummy from 2 to 28.
        (CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE,
        CLASSTYPE_REPLACEABLE_IF_ELIGIBLE, CLASSTYPE_TRIVIALLY_RELOCATABLE,
        CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED, CLASSTYPE_REPLACEABLE,
        CLASSTYPE_REPLACEABLE_COMPUTED): Define.
        (enum virt_specifier): Add VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE
        and VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE enumerators.
        (trivially_relocatable_type_p, replaceable_type_p): Declare.
        * cp-trait.def (IS_NOTHROW_RELOCATABLE, IS_REPLACEABLE,
        IS_TRIVIALLY_RELOCATABLE): New traits.
        * parser.cc (cp_parser_class_property_specifier_seq_opt): Handle
        trivially_relocatable_if_eligible,
        __trivially_relocatable_if_eligible, replaceable_if_eligible and
        __replaceable_if_eligible.
        (cp_parser_class_head): Set CLASSTYPE_REPLACEABLE_IF_ELIGIBLE
        and/or CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE if corresponding
        conditional keywords were parsed.
        * pt.cc (instantiate_class_template): Copy over also
        CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE and
        CLASSTYPE_REPLACEABLE_IF_ELIGIBLE bits.
        * semantics.cc (referenceable_type_p): Move definition earlier.
        (trait_expr_value): Handle CPTK_IS_NOTHROW_RELOCATABLE,
        CPTK_IS_REPLACEABLE and CPTK_IS_TRIVIALLY_RELOCATABLE.
        (finish_trait_expr): Likewise.
        * tree.cc (default_movable_type_p): New function.
        (union_with_no_declared_special_member_fns): Likewise.
        (trivially_relocatable_type_p): Likewise.
        (replaceable_type_p): Likewise.
        * constraint.cc (diagnose_trait_expr): Handle
        CPTK_IS_NOTHROW_RELOCATABLE, CPTK_IS_REPLACEABLE and
        CPTK_IS_TRIVIALLY_RELOCATABLE.
gcc/testsuite/
        * g++.dg/cpp26/feat-cxx26.C: Add test for
        __cpp_trivial_relocatability.
        * g++.dg/cpp26/trivially-relocatable1.C: New test.
        * g++.dg/cpp26/trivially-relocatable2.C: New test.
        * g++.dg/cpp26/trivially-relocatable3.C: New test.
        * g++.dg/cpp26/trivially-relocatable4.C: New test.
        * g++.dg/cpp26/trivially-relocatable5.C: New test.
        * g++.dg/cpp26/trivially-relocatable6.C: New test.
        * g++.dg/cpp26/trivially-relocatable7.C: New test.
        * g++.dg/cpp26/trivially-relocatable8.C: New test.
        * g++.dg/cpp26/trivially-relocatable9.C: New test.
        * g++.dg/cpp26/trivially-relocatable10.C: New test.
        * g++.dg/cpp26/trivially-relocatable11.C: New test.

--- gcc/c-family/c.opt.jj       2025-06-12 09:48:50.064307296 +0200
+++ gcc/c-family/c.opt  2025-06-13 14:50:24.533527899 +0200
@@ -493,6 +493,10 @@ Wc++20-compat
 C++ ObjC++ Var(warn_cxx20_compat) Warning LangEnabledBy(C++ ObjC++,Wall) 
Init(0) CPP(cpp_warn_cxx20_compat) CppReason(CPP_W_CXX20_COMPAT)
 Warn about C++ constructs whose meaning differs between ISO C++ 2017 and ISO 
C++ 2020.
 
+Wc++26-compat
+C++ ObjC++ Var(warn_cxx26_compat) Warning LangEnabledBy(C++ ObjC++,Wall) 
Init(0)
+Warn about C++ constructs whose meaning differs between ISO C++ 2023 and ISO 
C++ 2026.
+
 Wc++11-extensions
 C++ ObjC++ Var(warn_cxx11_extensions) Warning Init(1)
 Warn about C++11 constructs in code compiled with an older standard.
--- gcc/c-family/c.opt.urls.jj  2025-06-12 09:48:50.122306526 +0200
+++ gcc/c-family/c.opt.urls     2025-06-13 14:50:24.718525502 +0200
@@ -187,6 +187,9 @@ UrlSuffix(gcc/Warning-Options.html#index
 Wc++20-compat
 UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b20-compat)
 
+Wc++26-compat
+UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b26-compat)
+
 Wc++11-extensions
 UrlSuffix(gcc/Warning-Options.html#index-Wc_002b_002b11-extensions)
 
--- gcc/c-family/c-opts.cc.jj   2025-06-12 09:48:50.000308146 +0200
+++ gcc/c-family/c-opts.cc      2025-06-13 14:50:24.479528598 +0200
@@ -1165,6 +1165,9 @@ c_common_post_options (const char **pfil
       warn_cxx20_compat = 0;
       cpp_opts->cpp_warn_cxx20_compat = 0;
     }
+  if (cxx_dialect >= cxx26)
+    /* Don't warn about C++26 compatibility changes in C++26 or later.  */
+    warn_cxx26_compat = 0;
 
   /* C++17 has stricter evaluation order requirements; let's use some of them
      for earlier C++ as well, so chaining works as expected.  */
--- gcc/c-family/c-cppbuiltin.cc.jj     2025-06-12 09:48:49.829310417 +0200
+++ gcc/c-family/c-cppbuiltin.cc        2025-06-13 14:50:24.496528378 +0200
@@ -1094,6 +1094,7 @@ c_cpp_builtins (cpp_reader *pfile)
          cpp_define (pfile, "__cpp_variadic_friend=202403L");
          cpp_define (pfile, "__cpp_pack_indexing=202311L");
          cpp_define (pfile, "__cpp_pp_embed=202502L");
+         cpp_define (pfile, "__cpp_trivial_relocatability=202502L");
        }
       if (flag_concepts && cxx_dialect > cxx14)
        cpp_define (pfile, "__cpp_concepts=202002L");
--- gcc/cp/cp-tree.h.jj 2025-06-12 09:49:19.747913102 +0200
+++ gcc/cp/cp-tree.h    2025-06-13 14:50:24.450528973 +0200
@@ -2492,6 +2492,13 @@ struct GTY(()) lang_type {
   bool erroneous : 1;
   bool non_pod_aggregate : 1;
   bool non_aggregate_pod : 1;
+  bool trivially_relocatable_if_eligible : 1;
+  bool replaceable_if_eligible : 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
@@ -2500,7 +2507,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 : 2;
+  unsigned dummy : 28;
 
   tree primary_base;
   vec<tree_pair_s, va_gc> *vcall_indices;
@@ -2836,6 +2843,34 @@ 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)
+
+/* True if this class is marked with trivially_relocatable_if_eligible
+   conditional keyword.  */
+#define CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->trivially_relocatable_if_eligible)
+
+/* True if this class is marked with replaceable_if_eligible conditional
+   keyword.  */
+#define CLASSTYPE_REPLACEABLE_IF_ELIGIBLE(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->replaceable_if_eligible)
+
+/* True if this class is trivially relocatable.  */
+#define CLASSTYPE_TRIVIALLY_RELOCATABLE(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)
+
+/* True if this class is replaceable.  */
+#define CLASSTYPE_REPLACEABLE(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.  */
 
@@ -6463,7 +6498,9 @@ enum virt_specifier
   {
     VIRT_SPEC_UNSPECIFIED = 0x0,
     VIRT_SPEC_FINAL       = 0x1,
-    VIRT_SPEC_OVERRIDE    = 0x2
+    VIRT_SPEC_OVERRIDE    = 0x2,
+    VIRT_SPEC_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE = 0x4,
+    VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE = 0x8
   };
 
 /* A type-qualifier, or bitmask therefore, using the VIRT_SPEC
@@ -8231,6 +8268,8 @@ 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 trivially_copyable_p               (const_tree);
 extern bool type_has_unique_obj_representations (const_tree);
 extern bool scalarish_type_p                   (const_tree);
--- gcc/cp/cp-trait.def.jj      2025-06-12 09:48:50.611300032 +0200
+++ gcc/cp/cp-trait.def 2025-06-13 14:50:24.410529492 +0200
@@ -87,12 +87,14 @@ 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)
@@ -101,6 +103,7 @@ 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-06-13 14:50:09.256725765 +0200
+++ gcc/cp/parser.cc    2025-06-13 14:50:24.416529414 +0200
@@ -28012,6 +28012,8 @@ 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.  */
 
@@ -28044,6 +28046,38 @@ 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;
 
@@ -28599,6 +28633,10 @@ 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))
+    CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE (type) = 1;
+  if (type && (virt_specifiers & VIRT_SPEC_REPLACEABLE_IF_ELIGIBLE))
+    CLASSTYPE_REPLACEABLE_IF_ELIGIBLE (type) = 1;
  out:
   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   return type;
--- gcc/cp/pt.cc.jj     2025-06-12 09:48:51.130293140 +0200
+++ gcc/cp/pt.cc        2025-06-13 14:50:24.394529699 +0200
@@ -12700,7 +12700,13 @@ instantiate_class_template (tree type)
       determine_visibility (TYPE_MAIN_DECL (type));
     }
   if (CLASS_TYPE_P (type))
-    CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern);
+    {
+      CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern);
+      CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE (type)
+        = CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE (pattern);
+      CLASSTYPE_REPLACEABLE_IF_ELIGIBLE (type)
+        = CLASSTYPE_REPLACEABLE_IF_ELIGIBLE (pattern);
+    }
 
   pbinfo = TYPE_BINFO (pattern);
 
--- gcc/cp/semantics.cc.jj      2025-06-12 09:48:51.180292476 +0200
+++ gcc/cp/semantics.cc 2025-06-13 14:50:24.368530035 +0200
@@ -13359,6 +13359,18 @@ object_type_p (const_tree type)
           && !VOID_TYPE_P (type));
 }
 
+/* [defns.referenceable] True iff TYPE is a referenceable type.  */
+
+static bool
+referenceable_type_p (const_tree type)
+{
+  return (TYPE_REF_P (type)
+         || object_type_p (type)
+         || (FUNC_OR_METHOD_TYPE_P (type)
+             && (type_memfn_quals (type) == TYPE_UNQUALIFIED
+                 && type_memfn_rqual (type) == REF_QUAL_NONE)));
+}
+
 /* Actually evaluates the trait.  */
 
 static bool
@@ -13528,6 +13540,19 @@ 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);
+         return (referenceable_type_p (type1)
+                 && is_nothrow_xible (INIT_EXPR, type1,
+                                      cp_build_reference_type (type1,
+                                                               /*rval=*/true))
+                 && is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE));
+       }
+
     case CPTK_IS_OBJECT:
       return object_type_p (type1);
 
@@ -13546,6 +13571,9 @@ 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);
 
@@ -13570,6 +13598,9 @@ 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);
 
@@ -13698,18 +13729,6 @@ same_type_ref_bind_p (cp_trait_kind kind
              (non_reference (to), non_reference (from))));
 }
 
-/* [defns.referenceable] True iff TYPE is a referenceable type.  */
-
-static bool
-referenceable_type_p (const_tree type)
-{
-  return (TYPE_REF_P (type)
-         || object_type_p (type)
-         || (FUNC_OR_METHOD_TYPE_P (type)
-             && (type_memfn_quals (type) == TYPE_UNQUALIFIED
-                 && type_memfn_rqual (type) == REF_QUAL_NONE)));
-}
-
 /* Process a trait expression.  */
 
 tree
@@ -13752,8 +13771,11 @@ 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-06-12 09:48:51.224291891 +0200
+++ gcc/cp/tree.cc      2025-06-16 12:46:48.217705455 +0200
@@ -4715,6 +4715,292 @@ 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 (t);
+  if (!COMPLETE_TYPE_P (t))
+    return false;
+
+  if (!CLASSTYPE_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE (t)
+      && !union_with_no_declared_special_member_fns (t)
+      && !default_movable_type_p (t))
+    {
+    nontriv:
+      CLASSTYPE_TRIVIALLY_RELOCATABLE (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 (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 (t);
+  if (!COMPLETE_TYPE_P (t))
+    return false;
+
+  if (!CLASSTYPE_REPLACEABLE_IF_ELIGIBLE (t)
+      && !union_with_no_declared_special_member_fns (t)
+      && !default_movable_type_p (t))
+    {
+    nonrepl:
+      CLASSTYPE_REPLACEABLE (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 (t) = 1;
+  CLASSTYPE_REPLACEABLE_COMPUTED (t) = 1;
+  return true;
+}
+
 /* Returns 1 iff type T is a POD type, as defined in [basic.types].  */
 
 bool
--- gcc/cp/constraint.cc.jj     2025-06-12 09:48:50.611300032 +0200
+++ gcc/cp/constraint.cc        2025-06-13 14:50:24.425529297 +0200
@@ -3157,6 +3157,9 @@ diagnose_trait_expr (tree expr, tree arg
       else
        inform (loc, "  %qT is not nothrow invocable by %qE", t1, t2);
       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;
@@ -3176,6 +3179,9 @@ diagnose_trait_expr (tree expr, tree arg
     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, "  %qT is not the same as %qT", t1, t2);
       break;
@@ -3203,6 +3209,9 @@ diagnose_trait_expr (tree expr, tree arg
     case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
       inform (loc, "  %qT is not trivially destructible", t1);
       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/doc/invoke.texi.jj      2025-06-12 09:48:51.308290776 +0200
+++ gcc/doc/invoke.texi 2025-06-13 14:50:24.972522213 +0200
@@ -353,7 +353,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-builtin-macro-redefined  -Wc90-c99-compat  -Wc99-c11-compat
 -Wc11-c23-compat  -Wc23-c2y-compat
 -Wc++-compat  -Wc++11-compat  -Wc++14-compat  -Wc++17-compat
--Wc++20-compat
+-Wc++20-compat  -Wc++26-compat
 -Wno-c++11-extensions  -Wno-c++14-extensions -Wno-c++17-extensions
 -Wno-c++20-extensions  -Wno-c++23-extensions
 -Wcalloc-transposed-args
@@ -9625,6 +9625,12 @@ and ISO C++ 2017.  This warning is enabl
 Warn about C++ constructs whose meaning differs between ISO C++ 2017
 and ISO C++ 2020.  This warning is enabled by @option{-Wall}.
 
+@opindex Wc++26-compat
+@opindex Wno-c++26-compat
+@item -Wc++26-compat @r{(C++ and Objective-C++ only)}
+Warn about C++ constructs whose meaning differs between ISO C++ 2023
+and upcoming ISO C++ 2026.  This warning is enabled by @option{-Wall}.
+
 @opindex Wc++11-extensions
 @opindex Wno-c++11-extensions
 @item -Wno-c++11-extensions @r{(C++ and Objective-C++ only)}
--- gcc/testsuite/g++.dg/cpp26/feat-cxx26.C.jj  2025-06-02 11:00:06.220524528 
+0200
+++ gcc/testsuite/g++.dg/cpp26/feat-cxx26.C     2025-06-16 14:34:04.665828005 
+0200
@@ -634,3 +634,9 @@
 #elif __cpp_pp_embed != 202502
 #  error "__cpp_pp_embed != 202502"
 #endif
+
+#ifndef __cpp_trivial_relocatability
+# error "__cpp_trivial_relocatability"
+#elif __cpp_trivial_relocatability != 202502
+#  error "__cpp_trivial_relocatability != 202502"
+#endif
--- gcc/testsuite/g++.dg/cpp26/trivially-relocatable1.C.jj      2025-06-13 
14:50:24.458528870 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable1.C 2025-06-13 
18:20:12.558346274 +0200
@@ -0,0 +1,137 @@
+// 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-06-13 
14:56:36.330754007 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable2.C 2025-06-16 
11:14:58.076361036 +0200
@@ -0,0 +1,204 @@
+// 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-06-13 
15:18:33.829918971 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable3.C 2025-06-13 
18:54:12.621912128 +0200
@@ -0,0 +1,213 @@
+// 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-06-13 
18:21:45.710143237 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable4.C 2025-06-14 
19:38:23.628353410 +0200
@@ -0,0 +1,128 @@
+// 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-06-16 
09:33:43.795664691 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable5.C 2025-06-16 
10:39:43.901881363 +0200
@@ -0,0 +1,77 @@
+// 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-06-16 
10:25:27.258067137 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable6.C 2025-06-16 
10:40:52.386988182 +0200
@@ -0,0 +1,30 @@
+// 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-06-16 
11:13:26.503550912 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable7.C 2025-06-16 
11:18:34.533548463 +0200
@@ -0,0 +1,27 @@
+// 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_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_replaceable_v <A>;                    // { dg-message 
"required from here" }
--- gcc/testsuite/g++.dg/cpp26/trivially-relocatable8.C.jj      2025-06-16 
12:13:05.871038846 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable8.C 2025-06-16 
13:22:10.685038512 +0200
@@ -0,0 +1,158 @@
+// 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>, "");
+
+struct C { C (C &&) = default; C &operator= (C &&); ~C () = default; int a; };
+
+static_assert (!std::is_trivially_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_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_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_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_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_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_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_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_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_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_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_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_replaceable_v <O>, "");
+
+struct Q;
+struct P { template <typename T> P (T &&) {} };
+
+static_assert (std::is_trivially_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_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_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_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_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_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_replaceable_v <V>, "");
--- gcc/testsuite/g++.dg/cpp26/trivially-relocatable9.C.jj      2025-06-16 
13:11:02.046747323 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable9.C 2025-06-16 
14:15:27.319396081 +0200
@@ -0,0 +1,104 @@
+// 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 trivially_relocatable_if_eligible { A (A &&); A &operator= (A &&); ~A 
(); int a; };
+
+static_assert (std::is_trivially_relocatable_v <A>, "");
+
+struct B { B (B &&); B &operator= (B &&); ~B (); int a; };
+
+static_assert (!std::is_trivially_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>, "");
+
+struct D trivially_relocatable_if_eligible : public B { D (D &&); D &operator= 
(D &&); ~D (); int a; };
+
+static_assert (!std::is_trivially_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>, "");
+
+struct F trivially_relocatable_if_eligible { F (F &&); F &operator= (F &&); ~F 
(); B a; };
+
+static_assert (!std::is_trivially_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>, "");
+
+struct H trivially_relocatable_if_eligible : virtual A { H (H &&); H 
&operator= (H &&); ~H (); int a; };
+
+static_assert (!std::is_trivially_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>, "");
+
+struct J trivially_relocatable_if_eligible { J (J &&); J &operator= (J &&); ~J 
(); B &a; int &b; };
+
+static_assert (std::is_trivially_relocatable_v <J>, "");
+
+struct K trivially_relocatable_if_eligible { K (K &&); K &operator= (K &&); ~K 
(); union { A a; int b; char c; }; };
+
+static_assert (!std::is_trivially_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>, "");
+
+struct M trivially_relocatable_if_eligible { M (M &&); M &operator= (M &&); ~M 
() = default; int a; };
+
+static_assert (std::is_trivially_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>, "");
+
+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>, "");
--- gcc/testsuite/g++.dg/cpp26/trivially-relocatable10.C.jj     2025-06-16 
13:23:55.929667739 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable10.C        2025-06-16 
14:24:51.562039442 +0200
@@ -0,0 +1,135 @@
+// 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-06-16 
13:34:18.881555140 +0200
+++ gcc/testsuite/g++.dg/cpp26/trivially-relocatable11.C        2025-06-16 
13:59:30.799860570 +0200
@@ -0,0 +1,134 @@
+// 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>, "");

        Jakub

Reply via email to