Hi!

Here is a new version of the core P3666R5 patch, like previously on top of
https://gcc.gnu.org/pipermail/gcc-patches/2026-November/738467.html

Changes since the v2 version of the patch:
1) the module.cc ICE is resolved by not using finish_bitint there,
   instead building build_bitint or make_node (BITINT_TYPE) by hand
2) c_common_signed_or_unsigned_type and c_common_get_alias_set are fixed
   to support _BitInt(1) even for C++, previously it was just C2Y
3) tmpl<_BitInt(a > b ? 1 : 2)> is now handled correctly (> here is nested,
   so shouldn't be treated as template argument terminator)
4) similarly to C FE, when creating ARRAY_REFs with BITINT_TYPE index
   which has larger precision than sizetype, cast of the index to sizetype
   is added, because the middle-end is unprepared to handle ARRAY_REFs
   with large/huge _BitInt
5) 2 new testcases added

2026-11-13  Jakub Jelinek  <[email protected]>

        P3666R5
gcc/c-family/
        * c-lex.cc (interpret_integer): Handle 0wb as
        _BitInt(1) 0 for C++.
        * c-common.cc (c_common_reswords): Change C_ONLY to 0
        for _BitInt.
        (c_common_signed_or_unsigned_type): Handle signed _BitInt(1) even for
        C++.
        (c_common_get_alias_set): Likewise.
        * c-cppbuiltin.cc (c_cpp_builtins): Predefine __BITINT_MAXWIDTH__
        also for C++ when supported.  For C++29 also predefine __cpp_bit_int
        in that case as well.
gcc/cp/
        * parser.cc: Implement P3666R5 - Bit-precise integers.
        (cp_keyword_starts_decl_specifier_p): Handle RID_BITINT.
        (cp_parser_simple_type_specifier): Likewise.
        (set_and_check_decl_spec_loc): Add "_BitInt" name.
        * cp-tree.h (CP_INTEGRAL_CODE_P): Define.
        (CP_INTEGRAL_TYPE_P): Use CP_INTEGRAL_CODE_P.
        (INTEGRAL_CODE_P): Likewise.
        (INTEGRAL_OR_ENUMERATION_TYPE_P): Use INTEGRAL_CODE_P.
        (BITINT_PREC): Define.
        (enum cp_decl_spec): Add ds_bitint.
        (finish_bitint): Declare.
        * typeck.cc (cp_common_type): Emit sorry when trying to
        create common type for _Complex and _BitInt.  Handle the case
        where at least one type is bit-precise and they have the same
        precision.
        (structural_comptypes): Handle BITINT_TYPE.
        (cp_perform_integral_promotions): Likewise.
        (cp_build_array_ref): Use CP_INTEGRAL_TYPE_P macro.  If idx
        has BITINT_TYPE wider than sizetype, cast idx to sizetype.
        (cp_build_binary_op): Use CP_INTEGRAL_CODE_P or INTEGRAL_CODE_P
        macros where possible.  Handle BITINT_TYPE.
        (cp_build_c_cast): Handle BITINT_TYPE.
        (ptr_reasonably_similar): Likewise.
        (finish_bitint): New function.
        * decl.cc (reshape_init_array_1): Handle BITINT_TYPE.
        (grokdeclarator): Likewise.
        * pt.cc (find_parameter_packs_r): Likewise.
        (tsubst): Likewise.
        (uses_deducible_template_parms): Likewise.
        (array_deduction_r): Likewise.
        (unify): Likewise.
        (dependent_type_p_r): Likewise.
        * error.cc (dump_type): Likewise.
        (dump_type_prefix): Likewise.
        (dump_type_suffix): Likewise.
        (dump_expr): Likewise.
        * cxx-pretty-print.cc: Likewise.
        * tree.cc: Include target.h.
        (type_has_unique_obj_representations): Handle BITINT_TYPE.
        (cp_walk_subtrees): Likewise.
        * semantics.cc (finish_make_signed): Handle ENUMERAL_TYPE with
        BITINT_TYPE as underlying type.
        (handle_omp_for_class_iterator): Handle BITINT_TYPE.
        * call.cc (null_ptr_cst_p): Likewise.
        (build_list_conv): Likewise.
        (standard_conversion): Likewise.
        (build_conditional_expr): Likewise.
        (convert_like_internal): Likewise.
        (joust): Likewise.
        * constexpr.cc (cxx_eval_bit_field_ref): Likewise.
        (cxx_eval_outermost_constant_expr): Likewise.
        * cvt.cc (build_expr_type_conversion): Likewise.
        * init.cc (build_vec_init): Likewise.
        * mangle.cc (write_type): Likewise.
        (write_builtin_type): Likewise.
        * class.cc (layout_class_type): Likewise.
        * module.cc (trees_out::type_node, trees_in::tree_node): Likewise.
gcc/testsuite/
        * g++.dg/ext/bitint1.C: Remove.
        * g++.dg/ext/bitint2.C: Remove.
        * g++.dg/ext/bitint3.C: Remove.
        * g++.dg/ext/bitint4.C: Remove.
        * g++.dg/cpp29/bitint1.C: New test.
        * g++.dg/cpp29/bitint2.C: New test.
        * g++.dg/cpp29/bitint3.C: New test.
        * g++.dg/cpp29/bitint4.C: New test.
        * g++.dg/cpp29/bitint5.C: New test.
        * g++.dg/cpp29/bitint6.C: New test.
        * g++.dg/cpp29/bitint7.C: New test.
        * g++.dg/cpp29/bitint8.C: New test.
        * g++.dg/cpp29/bitint9.C: New test.
        * g++.dg/cpp29/bitint10.C: New test.
        * g++.dg/cpp29/bitint11.C: New test.
        * g++.dg/cpp29/bitint12.C: New test.
        * g++.dg/cpp29/bitint13.C: New test.
        * g++.dg/cpp29/bitint14.C: New test.
        * g++.dg/cpp29/bitint15.C: New test.
        * g++.dg/cpp29/bitint16.C: New test.
        * g++.dg/cpp29/bitint17.C: New test.
        * g++.dg/cpp29/bitint18.C: New test.
        * g++.dg/cpp29/bitint19.C: New test.
        * g++.dg/cpp29/bitint20.C: New test.
        * g++.dg/cpp29/bitint21.C: New test.
        * g++.dg/cpp29/bitint22.C: New test.
        * g++.dg/cpp29/bitint23.C: New test.
        * g++.dg/cpp29/bitint24.C: New test.
        * g++.dg/cpp29/bitint25.C: New test.
        * g++.dg/cpp29/bitint26.C: New test.
        * g++.dg/cpp29/bitint27.C: New test.
        * g++.dg/cpp29/bitint28.C: New test.
        * g++.dg/cpp29/bitint29.C: New test.
        * g++.dg/cpp29/bitint30.C: New test.
        * c-c++-common/builtin-bswapg-1.c: Use -Wno-c++29-extensions
        for c++26_down targets.
        * c-c++-common/builtin-bswapg-3.c: Likewise.
        * c-c++-common/builtin-bitreverseg-1.c: Likewise.
        * lib/target-supports.exp (check_effective_target_bitint,
        check_effective_target_bitint128, check_effective_target_bitint575,
        check_effective_target_bitint65535): For C++ use -std=c++29 rather
        than -std=c23.
libcpp/
        * expr.cc (interpret_int_suffix): Don't return 0 for wb
        for C++.
        (cpp_classify_number): Emit a pedwarn for C++ < 29 uses
        of wb.

--- a/gcc/c-family/c-lex.cc     2026-11-06 18:32:41.031466379 +0100
+++ b/gcc/c-family/c-lex.cc     2026-11-11 13:16:41.775559360 +0100
@@ -1094,7 +1094,8 @@ interpret_integer (const cpp_token *toke
        }
 
       prec = wi::min_precision (wval, UNSIGNED);
-      if (prec == 0 && ((flags & CPP_N_UNSIGNED) != 0 || !flag_isoc2y))
+      if (prec == 0 && ((flags & CPP_N_UNSIGNED) != 0
+                       || (!flag_isoc2y && !c_dialect_cxx ())))
        prec = 1;
       if ((flags & CPP_N_UNSIGNED) == 0)
        ++prec;
--- a/gcc/c-family/c-common.cc  2026-11-11 10:28:33.708007102 +0100
+++ b/gcc/c-family/c-common.cc  2026-11-13 11:30:31.606685086 +0100
@@ -400,7 +400,7 @@ const struct c_common_resword c_common_r
   { "_Maxof",          RID_MAXOF,     D_CONLY },
   { "_Minof",          RID_MINOF,     D_CONLY },
   { "_Atomic",         RID_ATOMIC,    D_CONLY },
-  { "_BitInt",         RID_BITINT,    D_CONLY },
+  { "_BitInt",         RID_BITINT,     0 },
   { "_Bool",           RID_BOOL,      D_CONLY },
   { "_Complex",                RID_COMPLEX,    0 },
   { "_Imaginary",      RID_IMAGINARY, D_CONLY },
@@ -2827,7 +2827,10 @@ c_common_signed_or_unsigned_type (int un
 
   if (BITINT_TYPE_P (type)
       /* signed _BitInt(1) is invalid before C2Y, avoid creating that.  */
-      && (unsignedp || flag_isoc2y || TYPE_PRECISION (type) > 1))
+      && (unsignedp
+         || TYPE_PRECISION (type) > 1
+         || flag_isoc2y
+         || c_dialect_cxx ()))
     return build_bitint_type (TYPE_PRECISION (type), unsignedp);
 
 #define TYPE_OK(node)                                                      \
@@ -3960,8 +3963,9 @@ c_common_get_alias_set (tree t)
        {
          /* There is no signed _BitInt(1) before C2Y.  */
          if (TREE_CODE (t) == BITINT_TYPE
+             && TYPE_PRECISION (t) == 1
              && !flag_isoc2y
-             && TYPE_PRECISION (t) == 1)
+             && !c_dialect_cxx ())
            return -1;
          tree t1 = c_common_signed_type (t);
          gcc_checking_assert (t != t1);
--- a/gcc/c-family/c-cppbuiltin.cc      2026-11-11 10:28:24.302131195 +0100
+++ b/gcc/c-family/c-cppbuiltin.cc      2026-11-11 13:16:41.809558912 +0100
@@ -1261,28 +1261,28 @@ c_cpp_builtins (cpp_reader *pfile)
   builtin_define_type_width ("__PTRDIFF_WIDTH__", ptrdiff_type_node, 
NULL_TREE);
   builtin_define_type_width ("__SIZE_WIDTH__", size_type_node, NULL_TREE);
 
-  if (!c_dialect_cxx ())
+  struct bitint_info info;
+  /* For now, restrict __BITINT_MAXWIDTH__ to what can be represented in
+     wide_int and widest_int.  */
+  if (targetm.c.bitint_type_info (WIDE_INT_MAX_PRECISION - 1, &info))
     {
-      struct bitint_info info;
-      /* For now, restrict __BITINT_MAXWIDTH__ to what can be represented in
-        wide_int and widest_int.  */
-      if (targetm.c.bitint_type_info (WIDE_INT_MAX_PRECISION - 1, &info))
+      cpp_define_formatted (pfile, "__BITINT_MAXWIDTH__=%d",
+                           (int) WIDE_INT_MAX_PRECISION - 1);
+      if (c_dialect_cxx () && cxx_dialect >= cxx29)
+       cpp_define_warn (pfile, "__cpp_bit_int=202611L");
+      if (flag_building_libgcc)
        {
-         cpp_define_formatted (pfile, "__BITINT_MAXWIDTH__=%d",
-                               (int) WIDE_INT_MAX_PRECISION - 1);
-         if (flag_building_libgcc)
-           {
-             scalar_int_mode limb_mode
-               = as_a <scalar_int_mode> (info.limb_mode);
-             cpp_define_formatted (pfile, "__LIBGCC_BITINT_LIMB_WIDTH__=%d",
-                                   (int) GET_MODE_PRECISION (limb_mode));
-             cpp_define_formatted (pfile, "__LIBGCC_BITINT_ORDER__=%s",
-                                   info.big_endian
-                                   ? "__ORDER_BIG_ENDIAN__"
-                                   : "__ORDER_LITTLE_ENDIAN__");
-           }
+         scalar_int_mode limb_mode = as_a <scalar_int_mode> (info.limb_mode);
+         cpp_define_formatted (pfile, "__LIBGCC_BITINT_LIMB_WIDTH__=%d",
+                               (int) GET_MODE_PRECISION (limb_mode));
+         cpp_define_formatted (pfile, "__LIBGCC_BITINT_ORDER__=%s",
+                               info.big_endian
+                               ? "__ORDER_BIG_ENDIAN__"
+                               : "__ORDER_LITTLE_ENDIAN__");
        }
     }
+  else if (c_dialect_cxx () && cxx_dialect >= cxx29)
+    cpp_warn (pfile, "__cpp_bit_int");
 
   if (c_dialect_cxx ())
     for (i = 0; i < NUM_INT_N_ENTS; i ++)
--- a/gcc/cp/parser.cc  2026-11-11 10:28:33.756006469 +0100
+++ b/gcc/cp/parser.cc  2026-11-12 20:11:13.165527461 +0100
@@ -1340,6 +1340,7 @@ cp_keyword_starts_decl_specifier_p (enum
     case RID_DOUBLE:
     CASE_RID_FLOATN_NX:
     case RID_VOID:
+    case RID_BITINT:
       /* CV qualifiers.  */
     case RID_CONST:
     case RID_VOLATILE:
@@ -22704,6 +22705,14 @@ cp_parser_type_specifier (cp_parser* par
 
      nested-name-specifier(opt) template-name
 
+   C++29 extension:
+
+   simple-type-specifier:
+     bit-precise-int-type-specifier
+
+   bit-precise-int-type-specifier:
+     _BitInt ( constant-expression )
+
    computed-type-specifier:
      decltype-specifier
      pack-index-specifier
@@ -22822,6 +22831,38 @@ cp_parser_simple_type_specifier (cp_pars
     case RID_VOID:
       type = void_type_node;
       break;
+    case RID_BITINT:
+      {
+       location_t loc = token->location;
+       if (cxx_dialect < cxx29 && pedantic)
+         pedwarn (loc, OPT_Wc__29_extensions,
+                  "%<_BitInt%> only available with "
+                  "%<-std=c++2d%> or %<-std=gnu++2d%>");
+       /* Consume the `_BitInt' token.  */
+       cp_lexer_consume_token (parser->lexer);
+       matching_parens parens;
+       if (!parens.require_open (parser))
+         return error_mark_node;
+        auto gr = make_temp_override (parser->greater_than_is_operator_p,
+                                     true);
+       tree prec
+         = cp_parser_constant_expression (parser,
+                                          /*allow_non_constant_p=*/false,
+                                          /*non_constant_p=*/nullptr,
+                                          /*strict_p=*/true);
+       if (!parens.require_close (parser))
+         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                                /*or_comma=*/false,
+                                                /*consume_paren=*/true);
+       if (check_for_bare_parameter_packs (prec))
+         prec = error_mark_node;
+       type = finish_bitint (loc, prec, false, tf_warning_or_error);
+       set_and_check_decl_spec_loc (decl_specs, ds_bitint, token);
+       if (decl_specs)
+         cp_parser_set_decl_spec_type (decl_specs, type, token,
+                                       /*type_definition_p=*/false);
+       return type;
+      }
 
     case RID_AUTO:
       maybe_warn_cpp0x (CPP0X_AUTO);
@@ -38031,6 +38072,7 @@ set_and_check_decl_spec_loc (cp_decl_spe
            "__complex",
            "constinit",
            "consteval",
+           "_BitInt",
            "this"
          };
          gcc_rich_location richloc (location);
--- a/gcc/cp/cp-tree.h  2026-11-11 12:32:33.493655185 +0100
+++ b/gcc/cp/cp-tree.h  2026-11-11 14:31:41.873252781 +0100
@@ -609,7 +609,8 @@ extern GTY(()) tree cp_global_trees[CPTI
      For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS.
      For a POINTER_TYPE (to a METHOD_TYPE), this is TYPE_PTRMEMFUNC_TYPE.
      For an ENUMERAL_TYPE, BOUND_TEMPLATE_TEMPLATE_PARM_TYPE,
-     RECORD_TYPE or UNION_TYPE this is TYPE_TEMPLATE_INFO,
+     RECORD_TYPE or UNION_TYPE this is TYPE_TEMPLATE_INFO.
+     For a BITINT_TYPE, this is BITINT_PREC.
 
   BINFO_VIRTUALS
      For a binfo, this is a TREE_LIST.  There is an entry for each
@@ -4911,29 +4912,29 @@ get_vec_init_expr (tree t)
 #define DECL_EXTERNAL_LINKAGE_P(DECL) \
   (decl_linkage (DECL) == lk_external)
 
-/* Keep these codes in ascending code order.  */
-
-#define INTEGRAL_CODE_P(CODE)  \
-  ((CODE) == ENUMERAL_TYPE     \
-   || (CODE) == BOOLEAN_TYPE   \
-   || (CODE) == INTEGER_TYPE)
-
 /* [basic.fundamental]
 
-   Types  bool, char, wchar_t, and the signed and unsigned integer types
+   Types bool, char, wchar_t, and the signed and unsigned integer types
    are collectively called integral types.
 
    Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration
    types as well, which is incorrect in C++.  Keep these checks in
    ascending code order.  */
+#define CP_INTEGRAL_CODE_P(CODE)               \
+  ((CODE) == BOOLEAN_TYPE                      \
+   || (CODE) == INTEGER_TYPE                   \
+   || (CODE) == BITINT_TYPE)
+
 #define CP_INTEGRAL_TYPE_P(TYPE)               \
-  (TREE_CODE (TYPE) == BOOLEAN_TYPE            \
-   || TREE_CODE (TYPE) == INTEGER_TYPE)
+  CP_INTEGRAL_CODE_P (TREE_CODE (TYPE))
 
-/* Returns true if TYPE is an integral or enumeration name.  Keep
-   these checks in ascending code order.  */
+/* Keep these codes in ascending code order.  */
+#define INTEGRAL_CODE_P(CODE)  \
+  ((CODE) == ENUMERAL_TYPE || CP_INTEGRAL_CODE_P (CODE))
+
+/* Returns true if TYPE is an integral or enumeration name.  */
 #define INTEGRAL_OR_ENUMERATION_TYPE_P(TYPE) \
-   (TREE_CODE (TYPE) == ENUMERAL_TYPE || CP_INTEGRAL_TYPE_P (TYPE))
+  INTEGRAL_CODE_P (TREE_CODE (TYPE))
 
 /* Returns true if TYPE is an integral or unscoped enumeration type.  */
 #define INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P(TYPE) \
@@ -5215,6 +5216,10 @@ get_vec_init_expr (tree t)
 #define INDIRECT_TYPE_P(NODE)                  \
   (TYPE_PTR_P (NODE) || TYPE_REF_P (NODE))
 
+/* Precision of BITINT_TYPE when dependent.  */
+#define BITINT_PREC(NODE) \
+  TYPE_LANG_SLOT_1 (BITINT_TYPE_CHECK (NODE))
+
 /* Returns true if NODE is an object type:
 
      [basic.types]
@@ -6979,6 +6984,7 @@ enum cp_decl_spec {
   ds_complex,
   ds_constinit,
   ds_consteval,
+  ds_bitint,
   ds_this, /* Index of last element of decl_spec_names.  */
   ds_thread,
   ds_type_spec,
@@ -9116,6 +9122,8 @@ extern tree finish_binary_fold_expr
 extern tree treat_lvalue_as_rvalue_p        (tree, bool);
 extern bool decl_in_std_namespace_p         (tree);
 extern void maybe_warn_pessimizing_move             (tree, tree, bool);
+extern tree finish_bitint                      (location_t, tree, bool,
+                                                tsubst_flags_t);
 
 /* in typeck2.cc */
 extern void require_complete_eh_spec_types     (tree, tree);
--- a/gcc/cp/typeck.cc  2026-11-11 10:28:33.761006403 +0100
+++ b/gcc/cp/typeck.cc  2026-11-12 19:17:15.180189418 +0100
@@ -473,6 +473,12 @@ cp_common_type (tree t1, tree t2)
 
       if (subtype == error_mark_node)
        return subtype;
+      if (TREE_CODE (subtype) == BITINT_TYPE)
+       {
+         sorry ("%<_Complex _BitInt(%d)%> unsupported",
+                TYPE_PRECISION (subtype));
+         subtype = code1 == COMPLEX_TYPE ? subtype1 : subtype2;
+       }
       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
        return build_type_attribute_variant (t1, attributes);
       else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
@@ -584,6 +590,24 @@ cp_common_type (tree t1, tree t2)
            }
        }
 
+      if ((code1 == BITINT_TYPE || code2 == BITINT_TYPE) && code1 != code2)
+       {
+         /* Prefer any other integral types over bit-precise integer
+            types.  */
+         if (TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2))
+           return build_type_attribute_variant (code1 == BITINT_TYPE
+                                                ? t2 : t1, attributes);
+         /* If BITINT_TYPE is unsigned and the other type is signed
+            non-BITINT_TYPE with the same precision, the latter has higher
+            rank, so the common type is the corresponding unsigned integer
+            type.  */
+         if (TYPE_UNSIGNED (code1 == BITINT_TYPE ? t1 : t2))
+           {
+             tree t = c_common_unsigned_type (code1 == BITINT_TYPE ? t2 : t1);
+             return build_type_attribute_variant (t, attributes);
+           }
+       }
+
       /* Otherwise prefer the unsigned one.  */
       if (TYPE_UNSIGNED (t1))
        return build_type_attribute_variant (t1, attributes);
@@ -1523,6 +1547,19 @@ structural_comptypes (tree t1, tree t2,
       /* We don't need or want the attribute comparison.  */
       goto check_alias;
 
+    case BITINT_TYPE:
+      /* Similar to INTEGER_TYPE, just have to compare BITINT_PREC for
+        dependent bit-precise integers.  */
+      if (TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
+       return false;
+      if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
+       return false;
+      if (TYPE_PRECISION (t1) == 0
+         && (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2)
+             || !cp_tree_equal (BITINT_PREC (t1), BITINT_PREC (t2))))
+       return false;
+      goto check_alias;
+
     case TEMPLATE_TEMPLATE_PARM:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       if (!comp_template_parms_position (t1, t2))
@@ -2781,6 +2818,7 @@ cp_perform_integral_promotions (tree exp
   tree bitfield_type = is_bitfield_expr_with_lowered_type (expr);
   if (bitfield_type
       && (TREE_CODE (bitfield_type) == ENUMERAL_TYPE
+         || TREE_CODE (bitfield_type) == BITINT_TYPE
          || TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)))
     type = bitfield_type;
 
@@ -4319,6 +4357,10 @@ cp_build_array_ref (location_t loc, tree
                        "subscripting array declared %<register%>");
        }
 
+      if (BITINT_TYPE_P (TREE_TYPE (idx))
+         && TYPE_PRECISION (TREE_TYPE (idx)) > TYPE_PRECISION (sizetype))
+       idx = fold_convert (sizetype, idx);
+
       type = TREE_TYPE (TREE_TYPE (array));
       rval = build4 (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
       /* Array ref is const/volatile if the array elements are
@@ -4346,7 +4388,7 @@ cp_build_array_ref (location_t loc, tree
       ar = first = save_expr (ar);
 
     /* Put the integer in IND to simplify error checking.  */
-    if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
+    if (CP_INTEGRAL_TYPE_P (TREE_TYPE (ar)))
       std::swap (ar, ind);
 
     if (ar == error_mark_node || ind == error_mark_node)
@@ -4358,7 +4400,7 @@ cp_build_array_ref (location_t loc, tree
          error_at (loc, "subscripted value is neither array nor pointer");
        return error_mark_node;
       }
-    if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
+    if (!CP_INTEGRAL_TYPE_P (TREE_TYPE (ind)))
       {
        if (complain & tf_error)
          error_at (loc, "array subscript is not an integer");
@@ -5764,7 +5806,7 @@ cp_build_binary_op (const op_location_t
        }
       /* In all other cases except pointer - int, the usual arithmetic
         rules apply.  */
-      else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
+      else if (!(code0 == POINTER_TYPE && CP_INTEGRAL_CODE_P (code1)))
        {
          common = 1;
          break;
@@ -5773,13 +5815,13 @@ cp_build_binary_op (const op_location_t
         through.  */
       gcc_fallthrough ();
     case PLUS_EXPR:
-      if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
-         && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
+      if ((code0 == POINTER_TYPE && CP_INTEGRAL_CODE_P (code1))
+         || (code1 == POINTER_TYPE && CP_INTEGRAL_CODE_P (code0)))
        {
          tree ptr_operand;
          tree int_operand;
-         ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
-         int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
+         ptr_operand = (code0 == POINTER_TYPE) ? op0 : op1;
+         int_operand = (code0 == POINTER_TYPE) ? op1 : op0;
          if (processing_template_decl)
            {
              result_type = TREE_TYPE (ptr_operand);
@@ -5842,9 +5884,9 @@ cp_build_binary_op (const op_location_t
                                         op1, non_reference (type1));
        }
 
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+      if ((CP_INTEGRAL_CODE_P (code0) || code0 == REAL_TYPE
           || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
-         && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+         && (CP_INTEGRAL_CODE_P (code1) || code1 == REAL_TYPE
              || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
        {
          enum tree_code tcode0 = code0, tcode1 = code1;
@@ -5856,9 +5898,9 @@ cp_build_binary_op (const op_location_t
          if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
            tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
 
-         if (!((tcode0 == INTEGER_TYPE
+         if (!(((tcode0 == INTEGER_TYPE || tcode0 == BITINT_TYPE)
                 || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
-               && (tcode1 == INTEGER_TYPE
+               && ((tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE)
                    || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))))
            resultcode = RDIV_EXPR;
          else
@@ -5879,7 +5921,7 @@ cp_build_binary_op (const op_location_t
     case BIT_AND_EXPR:
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
-      if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      if ((CP_INTEGRAL_CODE_P (code0) && CP_INTEGRAL_CODE_P (code1))
          || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
              && !VECTOR_FLOAT_TYPE_P (type0)
              && !VECTOR_FLOAT_TYPE_P (type1)))
@@ -5895,7 +5937,7 @@ cp_build_binary_op (const op_location_t
          && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
          && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
        common = 1;
-      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      else if (CP_INTEGRAL_CODE_P (code0) && CP_INTEGRAL_CODE_P (code1))
        {
          /* Although it would be tempting to shorten always here, that loses
             on some targets, since the modulo instruction is undefined if the
@@ -5957,8 +5999,10 @@ cp_build_binary_op (const op_location_t
 
       if (warn_constant_logical_operand
          && (complain & tf_warning)
-         && (code0 == INTEGER_TYPE || code0 == ENUMERAL_TYPE)
-         && (code1 == INTEGER_TYPE || code1 == ENUMERAL_TYPE))
+         && (code0 == INTEGER_TYPE || code0 == BITINT_TYPE
+             || code0 == ENUMERAL_TYPE)
+         && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE
+             || code1 == ENUMERAL_TYPE))
        {
          tree cop0 = fold_for_warn (op0), cop1 = fold_for_warn (op1);
          const char *name
@@ -6002,7 +6046,7 @@ cp_build_binary_op (const op_location_t
 
     case RSHIFT_EXPR:
       if (gnu_vector_type_p (type0)
-         && code1 == INTEGER_TYPE
+         && CP_INTEGRAL_CODE_P (code1)
          && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
         {
           result_type = type0;
@@ -6018,7 +6062,7 @@ cp_build_binary_op (const op_location_t
          result_type = type0;
          converted = 1;
        }
-      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      else if (CP_INTEGRAL_CODE_P (code0) && CP_INTEGRAL_CODE_P (code1))
        {
          tree const_op1 = fold_for_warn (op1);
          if (TREE_CODE (const_op1) != INTEGER_CST)
@@ -6053,7 +6097,7 @@ cp_build_binary_op (const op_location_t
 
     case LSHIFT_EXPR:
       if (gnu_vector_type_p (type0)
-         && code1 == INTEGER_TYPE
+         && CP_INTEGRAL_CODE_P (code1)
           && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE)
         {
           result_type = type0;
@@ -6069,7 +6113,7 @@ cp_build_binary_op (const op_location_t
          result_type = type0;
          converted = 1;
        }
-      else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+      else if (CP_INTEGRAL_CODE_P (code0) && CP_INTEGRAL_CODE_P (code1))
        {
          tree const_op0 = fold_for_warn (op0);
          if (TREE_CODE (const_op0) != INTEGER_CST)
@@ -6146,10 +6190,10 @@ cp_build_binary_op (const op_location_t
       }
 
       build_type = boolean_type_node;
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
-          || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
-         && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-             || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
+      if ((INTEGRAL_CODE_P (code0) || code0 == REAL_TYPE
+          || code0 == COMPLEX_TYPE)
+         && (INTEGRAL_CODE_P (code1) || code1 == REAL_TYPE
+             || code1 == COMPLEX_TYPE))
        short_compare = 1;
       else if (((code0 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type0))
                && null_ptr_cst_p (orig_op1))
@@ -6207,7 +6251,7 @@ cp_build_binary_op (const op_location_t
       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
        /* One of the operands must be of nullptr_t type.  */
         result_type = TREE_TYPE (nullptr_node);
-      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+      else if (code0 == POINTER_TYPE && CP_INTEGRAL_CODE_P (code1))
        {
          result_type = type0;
          if (complain & tf_error)
@@ -6216,7 +6260,7 @@ cp_build_binary_op (const op_location_t
           else
             return error_mark_node;
        }
-      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+      else if (CP_INTEGRAL_CODE_P (code0) && code1 == POINTER_TYPE)
        {
          result_type = type1;
          if (complain & tf_error)
@@ -6404,8 +6448,8 @@ cp_build_binary_op (const op_location_t
 
     case MAX_EXPR:
     case MIN_EXPR:
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
-          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+      if ((CP_INTEGRAL_CODE_P (code0) || code0 == REAL_TYPE)
+         && (CP_INTEGRAL_CODE_P (code1) || code1 == REAL_TYPE))
        shorten = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        result_type = composite_pointer_type (location,
@@ -6513,10 +6557,8 @@ cp_build_binary_op (const op_location_t
          return build_vec_cmp (resultcode, result_type, op0, op1);
        }
       build_type = boolean_type_node;
-      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
-          || code0 == ENUMERAL_TYPE)
-          && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-              || code1 == ENUMERAL_TYPE))
+      if ((INTEGRAL_CODE_P (code0) || code0 == REAL_TYPE)
+         && (INTEGRAL_CODE_P (code1) || code1 == REAL_TYPE))
        short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        result_type = composite_pointer_type (location,
@@ -6532,7 +6574,7 @@ cp_build_binary_op (const op_location_t
                      "integer zero (%qT and %qT)", type0, type1);
          return error_mark_node;
        }
-      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+      else if (code0 == POINTER_TYPE && CP_INTEGRAL_CODE_P (code1))
        {
          result_type = type0;
          if (complain & tf_error)
@@ -6541,7 +6583,7 @@ cp_build_binary_op (const op_location_t
          else
             return error_mark_node;
        }
-      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+      else if (CP_INTEGRAL_CODE_P (code0) && code1 == POINTER_TYPE)
        {
          result_type = type1;
          if (complain & tf_error)
@@ -6585,10 +6627,9 @@ cp_build_binary_op (const op_location_t
       break;
     }
 
-  if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
-       || code0 == ENUMERAL_TYPE)
-       && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
-          || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
+  if ((INTEGRAL_CODE_P (code0) || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+      && (INTEGRAL_CODE_P (code1) || code1 == REAL_TYPE
+         || code1 == COMPLEX_TYPE))
     arithmetic_types_p = 1;
   else
     {
@@ -9851,7 +9892,8 @@ cp_build_c_cast (location_t loc, tree ty
     }
 
   if (TYPE_PTR_P (type)
-      && TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
+      && (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
+         || TREE_CODE (TREE_TYPE (value)) == BITINT_TYPE)
       /* Casting to an integer of smaller size is an error detected elsewhere. 
 */
       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
       /* Don't warn about converting any constant.  */
@@ -12167,7 +12209,8 @@ ptr_reasonably_similar (const_tree to, c
          && vector_types_convertible_p (to, from, false))
        return true;
 
-      if (TREE_CODE (to) == INTEGER_TYPE
+      if ((TREE_CODE (to) == INTEGER_TYPE
+          || TREE_CODE (to) == BITINT_TYPE)
          && TYPE_PRECISION (to) == TYPE_PRECISION (from))
        return true;
 
@@ -12633,6 +12676,60 @@ check_literal_operator_args (const_tree
     }
 }
 
+/* Finish a BITINT_TYPE with precision PREC.  */
+
+tree
+finish_bitint (location_t loc, tree prec, bool unsignedp,
+              tsubst_flags_t complain)
+{
+  if (!type_dependent_expression_p (prec))
+    prec = build_converted_constant_expr (size_type_node, prec, complain);
+  prec = fold_non_dependent_expr (prec, complain, true);
+  if (error_operand_p (prec))
+    return error_mark_node;
+  if (TREE_CODE (prec) == INTEGER_CST)
+    {
+      if (integer_zerop (prec))
+       {
+         if (complain & tf_error)
+           error_at (loc, "%<_BitInt%> argument %qE is not a positive "
+                          "integer constant expression", prec);
+         return error_mark_node;
+       }
+      else if (wi::to_widest (prec) > WIDE_INT_MAX_PRECISION - 1)
+       {
+         if (complain & tf_error)
+           error_at (loc, "%<_BitInt%> argument %qE is larger than "
+                          "%<BITINT_MAXWIDTH%> %qd",
+                     prec, (int) WIDE_INT_MAX_PRECISION - 1);
+         return error_mark_node;
+       }
+      unsigned int p = tree_to_uhwi (prec);
+      struct bitint_info info;
+      if (!targetm.c.bitint_type_info (p, &info))
+       {
+         if (complain & tf_error)
+           sorry_at (loc, "%<_BitInt(%d)%> is not supported on this "
+                          "target", p);
+         return error_mark_node;
+       }
+      return build_bitint_type (p, unsignedp);
+    }
+  else if (!value_dependent_expression_p (prec))
+    {
+      if (complain & tf_error)
+       error_at (loc, "%<_BitInt%> argument is not an integer "
+                      "constant expression");
+      return error_mark_node;
+    }
+  tree ret = make_node (BITINT_TYPE);
+  TYPE_PRECISION (ret) = 0;
+  TYPE_UNSIGNED (ret) = unsignedp;
+  BITINT_PREC (ret) = prec;
+  SET_TYPE_STRUCTURAL_EQUALITY (ret);
+  return ret;
+}
+
 /* Always returns false since unlike C90, C++ has no concept of implicit
    function declarations.  */
 
--- a/gcc/cp/decl.cc    2026-11-11 10:28:33.749006561 +0100
+++ b/gcc/cp/decl.cc    2026-11-11 13:16:41.819992887 +0100
@@ -7709,6 +7709,7 @@ reshape_init_array_1 (tree elt_type, tre
       check_array_designated_initializer (d->cur, index);
       if (TREE_CODE (d->cur->value) == RAW_DATA_CST
          && (TREE_CODE (elt_type) == INTEGER_TYPE
+             || TREE_CODE (elt_type) == BITINT_TYPE
              || is_byte_access_type (elt_type))
          && TYPE_PRECISION (elt_type) == CHAR_BIT
          && (!sized_array_p || index < max_index_cst)
@@ -14253,6 +14254,7 @@ grokdeclarator (const cp_declarator *dec
   bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
   bool constinit_p = decl_spec_seq_has_spec_p (declspecs, ds_constinit);
   bool consteval_p = decl_spec_seq_has_spec_p (declspecs, ds_consteval);
+  bool bitint_p = decl_spec_seq_has_spec_p (declspecs, ds_bitint);
   bool late_return_type_p = false;
   bool array_parameter_p = false;
   tree reqs = NULL_TREE;
@@ -14774,15 +14776,19 @@ grokdeclarator (const cp_declarator *dec
        complain_about_incompatible_declspecs
          ("long", declspecs->locations[ds_long],
           "short", declspecs->locations[ds_short]);
-      else if (TREE_CODE (type) != INTEGER_TYPE
+      else if ((TREE_CODE (type) != INTEGER_TYPE
+               && TREE_CODE (type) != BITINT_TYPE)
               || type == char8_type_node
               || type == char16_type_node
               || type == char32_type_node
               || ((long_p || short_p)
-                  && (explicit_char || explicit_intN)))
+                  && (explicit_char
+                      || explicit_intN
+                      || TREE_CODE (type) == BITINT_TYPE)))
        error_at (loc, "%qs specified with %qT", key, type);
       else if (!explicit_int && !defaulted_int
-              && !explicit_char && !explicit_intN)
+              && !explicit_char && !explicit_intN
+              && !bitint_p)
        {
          if (typedef_decl)
            {
@@ -14845,6 +14851,16 @@ grokdeclarator (const cp_declarator *dec
        type = short_unsigned_type_node;
       else if (type == char_type_node)
        type = unsigned_char_type_node;
+      else if (TREE_CODE (type) == BITINT_TYPE)
+       {
+         if (TYPE_PRECISION (type))
+           type = c_common_unsigned_type (type);
+         else
+           {
+             type = build_distinct_type_copy (type);
+             TYPE_UNSIGNED (type) = 1;
+           }
+       }
       else if (typedef_decl)
        type = c_common_unsigned_type (type);
       else
--- a/gcc/cp/pt.cc      2026-11-11 10:28:33.758006442 +0100
+++ b/gcc/cp/pt.cc      2026-11-11 13:16:41.822558740 +0100
@@ -4248,6 +4248,15 @@ find_parameter_packs_r (tree *tp, int *w
       *walk_subtrees = 0;
       return NULL_TREE;
 
+    case BITINT_TYPE:
+      if (TYPE_PRECISION (t) == 0)
+       {
+         cp_walk_tree (&BITINT_PREC (t), &find_parameter_packs_r,
+                       ppd, ppd->visited);
+       }
+      *walk_subtrees = 0;
+      return NULL_TREE;
+
     case IDENTIFIER_NODE:
       cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd,
                    ppd->visited);
@@ -17428,6 +17437,16 @@ tsubst (tree t, tree args, tsubst_flags_
        return compute_array_index_type (NULL_TREE, max, complain);
       }
 
+    case BITINT_TYPE:
+      if (TYPE_PRECISION (t))
+       return t;
+      else
+       {
+         tree prec = tsubst_expr (BITINT_PREC (t), args, complain, in_decl);
+         return finish_bitint (input_location, prec, TYPE_UNSIGNED (t),
+                               complain);
+       }
+
     case TEMPLATE_TYPE_PARM:
       if (TEMPLATE_TYPE_LEVEL (t) == 0)
        {
@@ -24993,6 +25012,11 @@ uses_deducible_template_parms (tree type
     return (uses_deducible_template_parms (TREE_TYPE (type))
            || deducible_array_bound (TYPE_DOMAIN (type)));
 
+  /* _BitInt(i)  */
+  if (TREE_CODE (type) == BITINT_TYPE
+      && TYPE_PRECISION (type) == 0)
+    return deducible_expression (BITINT_PREC (type));
+
   /* T type ::*
      type T::*
      T T::*
@@ -25164,6 +25188,12 @@ array_deduction_r (tree t, void *data)
                   UNIFY_ALLOW_NONE, /*explain*/false);
        }
 
+  if (TREE_CODE (t) == BITINT_TYPE
+      && TYPE_PRECISION (t) == 0
+      && TREE_CODE (BITINT_PREC (t)) == TEMPLATE_PARM_INDEX)
+    unify (tparms, targs, TREE_TYPE (BITINT_PREC (t)), size_type_node,
+          UNIFY_ALLOW_NONE, /*explain*/false);
+
   /* Keep walking.  */
   return 0;
 }
@@ -25171,7 +25201,7 @@ array_deduction_r (tree t, void *data)
 /* Try to deduce any not-yet-deduced template type arguments from the type of
    an array bound.  This is handled separately from unify because 14.8.2.5 says
    "The type of a type parameter is only deduced from an array bound if it is
-   not otherwise deduced."  */
+   not otherwise deduced."  Also handles _BitInt width deduction.  */
 
 static void
 try_array_deduction (tree tparms, tree targs, tree parm)
@@ -26947,6 +26977,28 @@ unify (tree tparms, tree targs, tree par
         will invalidate it if necessary.  */
       return unify_success (explain_p);
 
+    case BITINT_TYPE:
+      if (TREE_CODE (arg) != BITINT_TYPE
+         || TYPE_UNSIGNED (arg) != TYPE_UNSIGNED (parm))
+       return unify_type_mismatch (explain_p, parm, arg);
+      if (TYPE_PRECISION (arg) == 0 || TYPE_PRECISION (parm) == 0)
+       {
+         tree arg_prec, parm_prec;
+         if (TYPE_PRECISION (arg) == 0)
+           arg_prec = BITINT_PREC (arg);
+         else
+           arg_prec = size_int (TYPE_PRECISION (arg));
+         if (TYPE_PRECISION (parm) == 0)
+           parm_prec = BITINT_PREC (parm);
+         else
+           parm_prec = size_int (TYPE_PRECISION (parm));
+         return unify (tparms, targs, parm_prec, arg_prec,
+                       UNIFY_ALLOW_INTEGER, explain_p);
+       }
+      if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))
+       return unify_type_mismatch (explain_p, parm, arg);
+      return unify_success (explain_p);
+
       /* Types INTEGER_CST and MINUS_EXPR can come from array bounds.  */
       /* Type INTEGER_CST can come from ordinary constant template args.  */
     case INTEGER_CST:
@@ -29909,6 +29961,12 @@ dependent_type_p_r (tree type)
       || TREE_CODE (type) == TRAIT_TYPE)
     return true;
 
+  /* Bit-precise integer types with value-dependent width are dependent.  */
+  if (TREE_CODE (type) == BITINT_TYPE
+      && TYPE_PRECISION (type) == 0
+      && BITINT_PREC (type))
+    return true;
+
   /* A template argument pack is dependent if any of its packed
      arguments are.  */
   if (TREE_CODE (type) == TYPE_ARGUMENT_PACK)
--- a/gcc/cp/error.cc   2026-11-11 10:28:33.749006561 +0100
+++ b/gcc/cp/error.cc   2026-11-11 13:16:41.824208069 +0100
@@ -766,6 +766,7 @@ dump_type (cxx_pretty_printer *pp, tree
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
     case FIXED_POINT_TYPE:
+    case BITINT_TYPE:
       pp_type_specifier_seq (pp, t);
       break;
 
@@ -1148,6 +1149,7 @@ dump_type_prefix (cxx_pretty_printer *pp
     case NULLPTR_TYPE:
     case PACK_INDEX_TYPE:
     case SPLICE_SCOPE:
+    case BITINT_TYPE:
       dump_type (pp, t, flags);
       pp->set_padding (pp_before);
       break;
@@ -1282,6 +1284,7 @@ dump_type_suffix (cxx_pretty_printer *pp
     case NULLPTR_TYPE:
     case PACK_INDEX_TYPE:
     case SPLICE_SCOPE:
+    case BITINT_TYPE:
       break;
 
     default:
@@ -3173,6 +3176,7 @@ dump_expr (cxx_pretty_printer *pp, tree
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
     case DECLTYPE_TYPE:
+    case BITINT_TYPE:
       pp_type_specifier_seq (pp, t);
       break;
 
--- a/gcc/cp/cxx-pretty-print.cc        2026-11-06 18:32:41.070465857 +0100
+++ b/gcc/cp/cxx-pretty-print.cc        2026-11-11 13:16:41.824613045 +0100
@@ -1442,6 +1442,21 @@ cxx_pretty_printer::simple_type_specifie
       pp_cxx_trait (this, t);
       break;
 
+    case BITINT_TYPE:
+      if (TYPE_NAME (t) == NULL_TREE
+         && TYPE_PRECISION (t) == 0
+         && BITINT_PREC (t))
+       {
+         if (TYPE_UNSIGNED (t))
+           pp_c_ws_string (this, "unsigned");
+         pp_c_ws_string (this, "_BitInt(");
+         expression (BITINT_PREC (t));
+         pp_right_paren (this);
+         break;
+       }
+      c_pretty_printer::simple_type_specifier (t);
+      break;
+
     case OPAQUE_TYPE:
       if (REFLECTION_TYPE_P (t))
        {
--- a/gcc/cp/tree.cc    2026-11-11 10:28:33.760006416 +0100
+++ b/gcc/cp/tree.cc    2026-11-11 13:16:41.824999313 +0100
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.
 #include "attribs.h"
 #include "flags.h"
 #include "selftest.h"
+#include "target.h"
 
 static tree bot_manip (tree *, int *, void *);
 static tree bot_replace (tree *, int *, void *);
@@ -5126,6 +5127,39 @@ type_has_unique_obj_representations (con
        inform (loc, "%qT is a fixed-point type", t);
       return false;
 
+    case BITINT_TYPE:
+      {
+       struct bitint_info info;
+       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (t), &info);
+       gcc_assert (ok);
+       if (info.extended == bitint_ext_full)
+         return true;
+       scalar_int_mode abi_limb_mode
+         = as_a <scalar_int_mode> (info.abi_limb_mode);
+       if (TYPE_PRECISION (t) < GET_MODE_PRECISION (abi_limb_mode))
+         {
+           if (info.extended == bitint_ext_partial)
+             return true;
+         }
+       else if (TYPE_PRECISION (t) == GET_MODE_PRECISION (abi_limb_mode))
+         return true;
+       else if ((((unsigned) TYPE_PRECISION (t))
+                 % GET_MODE_PRECISION (abi_limb_mode)) == 0)
+         return true;
+       else if (info.extended == bitint_ext_partial)
+         {
+           scalar_int_mode limb_mode
+             = as_a <scalar_int_mode> (info.limb_mode);
+           if ((ROUND_UP ((unsigned) TYPE_PRECISION (t),
+                          (unsigned) GET_MODE_PRECISION (limb_mode))
+                % GET_MODE_PRECISION (abi_limb_mode)) == 0)
+             return true;
+         }
+       if (explain)
+         inform (loc, "%qT has padding bits", t);
+       return false;
+      }
+
     case OFFSET_TYPE:
       return true;
 
@@ -6618,6 +6652,11 @@ cp_walk_subtrees (tree *tp, int *walk_su
       WALK_SUBTREE (TYPE_MAX_VALUE (t));
       break;
 
+    case BITINT_TYPE:
+      if (TYPE_PRECISION (t) == 0)
+       WALK_SUBTREE (BITINT_PREC (t));
+      break;
+
     case SPLICE_SCOPE:
       WALK_SUBTREE (SPLICE_SCOPE_EXPR (t));
       *walk_subtrees_p = 0;
--- a/gcc/cp/semantics.cc       2026-11-11 12:33:59.592518785 +0100
+++ b/gcc/cp/semantics.cc       2026-11-11 13:23:44.205992637 +0100
@@ -5358,11 +5358,14 @@ finish_make_signed (tree type, bool unsi
       return error_mark_node;
     }
   tree ret = type;
-  if (TREE_CODE (type) == ENUMERAL_TYPE
-      || TYPE_MAIN_VARIANT (type) == wchar_type_node
-      || TYPE_MAIN_VARIANT (type) == char8_type_node
-      || TYPE_MAIN_VARIANT (type) == char16_type_node
-      || TYPE_MAIN_VARIANT (type) == char32_type_node)
+  if (TREE_CODE (type) == ENUMERAL_TYPE && BITINT_TYPE_P (type))
+    ret = c_common_signed_or_unsigned_type (unsignedp,
+                                           ENUM_UNDERLYING_TYPE (type));
+  else if (TREE_CODE (type) == ENUMERAL_TYPE
+          || TYPE_MAIN_VARIANT (type) == wchar_type_node
+          || TYPE_MAIN_VARIANT (type) == char8_type_node
+          || TYPE_MAIN_VARIANT (type) == char16_type_node
+          || TYPE_MAIN_VARIANT (type) == char32_type_node)
     {
       tree unit = TYPE_SIZE_UNIT (type);
       tree types[] = {
@@ -11919,7 +11922,8 @@ handle_omp_for_class_iterator (int i, lo
   diff = cp_fully_fold (diff);
   if (error_operand_p (diff))
     return true;
-  if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
+  if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE
+      && TREE_CODE (TREE_TYPE (diff)) != BITINT_TYPE)
     {
       error_at (elocus, "difference between %qE and %qD does not have integer 
type",
                TREE_OPERAND (cond, 1), iter);
@@ -11962,7 +11966,9 @@ handle_omp_for_class_iterator (int i, lo
          if (TREE_OPERAND (rhs, 0) == iter)
            {
              if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
-                 != INTEGER_TYPE)
+                 != INTEGER_TYPE
+                 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
+                     != BITINT_TYPE))
                incr = error_mark_node;
              else
                {
@@ -11990,7 +11996,10 @@ handle_omp_for_class_iterator (int i, lo
            }
          else if (TREE_OPERAND (rhs, 1) == iter)
            {
-             if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE
+             if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0)))
+                  != INTEGER_TYPE
+                  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0)))
+                      != BITINT_TYPE))
                  || TREE_CODE (rhs) != PLUS_EXPR)
                incr = error_mark_node;
              else
--- a/gcc/cp/call.cc    2026-11-11 10:28:33.744006627 +0100
+++ b/gcc/cp/call.cc    2026-11-11 13:16:41.826982338 +0100
@@ -564,7 +564,8 @@ null_ptr_cst_p (tree t)
       /* Core issue 903 says only literal 0 is a null pointer constant.  */
       if (TREE_CODE (t) == INTEGER_CST
          && !TREE_OVERFLOW (t)
-         && TREE_CODE (type) == INTEGER_TYPE
+         && (TREE_CODE (type) == INTEGER_TYPE
+             || TREE_CODE (type) == BITINT_TYPE)
          && integer_zerop (t)
          && !char_type_p (type))
        return true;
@@ -888,6 +889,7 @@ build_list_conv (tree type, tree ctor, i
          if (sub->kind == ck_std
              && sub->type
              && (TREE_CODE (sub->type) == INTEGER_TYPE
+                 || TREE_CODE (sub->type) == BITINT_TYPE
                  || is_byte_access_type (sub->type))
              && TYPE_PRECISION (sub->type) == CHAR_BIT
              && (next = next_conversion (sub))
@@ -1400,15 +1402,18 @@ standard_conversion (tree to, tree from,
       && ((expr && null_ptr_cst_p (expr))
          || NULLPTR_TYPE_P (from)))
     conv = build_conv (ck_std, to, conv);
-  else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
-          || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
+  else if (((tcode == INTEGER_TYPE || tcode == BITINT_TYPE)
+           && fcode == POINTER_TYPE)
+          || (tcode == POINTER_TYPE
+              && (fcode == INTEGER_TYPE || fcode == BITINT_TYPE)))
     {
       /* For backwards brain damage compatibility, allow interconversion of
         pointers and integers with a pedwarn.  */
       conv = build_conv (ck_std, to, conv);
       conv->bad_p = true;
     }
-  else if (UNSCOPED_ENUM_P (to) && fcode == INTEGER_TYPE)
+  else if (UNSCOPED_ENUM_P (to)
+          && (fcode == INTEGER_TYPE || fcode == BITINT_TYPE))
     {
       /* For backwards brain damage compatibility, allow interconversion of
         enums and integers with a pedwarn.  */
@@ -6073,9 +6078,11 @@ build_conditional_expr (const op_locatio
   if ((TREE_CODE (arg2) == EXCESS_PRECISION_EXPR
        || TREE_CODE (arg3) == EXCESS_PRECISION_EXPR)
       && (TREE_CODE (arg2_type) == INTEGER_TYPE
+         || TREE_CODE (arg2_type) == BITINT_TYPE
          || SCALAR_FLOAT_TYPE_P (arg2_type)
          || TREE_CODE (arg2_type) == COMPLEX_TYPE)
       && (TREE_CODE (arg3_type) == INTEGER_TYPE
+         || TREE_CODE (arg3_type) == BITINT_TYPE
          || SCALAR_FLOAT_TYPE_P (arg3_type)
          || TREE_CODE (arg3_type) == COMPLEX_TYPE))
     {
@@ -9085,6 +9092,7 @@ convert_like_internal (conversion *convs
                        conversion *next = next_conversion (convs->u.list[ix]);
                        gcc_assert (et
                                    && (TREE_CODE (et) == INTEGER_TYPE
+                                       || TREE_CODE (et) == BITINT_TYPE
                                        || is_byte_access_type (et))
                                    && TYPE_PRECISION (et) == CHAR_BIT
                                    && next
@@ -13483,8 +13491,10 @@ joust (struct z_candidate *cand1, struct
                  == cr_std + cr_promotion)
              && t1->kind == ck_std
              && t2->kind == ck_std
-             && TREE_CODE (t1->type) == INTEGER_TYPE
-             && TREE_CODE (t2->type) == INTEGER_TYPE
+             && (TREE_CODE (t1->type) == INTEGER_TYPE
+                 || TREE_CODE (t1->type) == BITINT_TYPE)
+             && (TREE_CODE (t2->type) == INTEGER_TYPE
+                 || TREE_CODE (t2->type) == BITINT_TYPE)
              && (TYPE_PRECISION (t1->type)
                  == TYPE_PRECISION (t2->type))
              && (TYPE_UNSIGNED (next_conversion (t1)->type)
--- a/gcc/cp/constexpr.cc       2026-11-11 10:28:33.746006601 +0100
+++ b/gcc/cp/constexpr.cc       2026-11-11 13:16:41.828172106 +0100
@@ -6882,7 +6882,8 @@ cxx_eval_bit_field_ref (const constexpr_
       STRIP_ANY_LOCATION_WRAPPER (value);
       if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
        return value;
-      if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
+      if ((TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
+          || TREE_CODE (TREE_TYPE (field)) == BITINT_TYPE)
          && TREE_CODE (value) == INTEGER_CST
          && tree_fits_shwi_p (bitpos)
          && tree_fits_shwi_p (DECL_SIZE (field)))
@@ -11642,7 +11643,9 @@ cxx_eval_outermost_constant_expr (tree t
         we don't shortcut all vector constructors.  */
       if (fndecl && DECL_CONSTRUCTOR_P (fndecl) && allow_non_constant
          && is_std_class (type, "vector") && call_expr_nargs (x) > 1
-         && TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE)
+         && (TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE
+             || (TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1)))
+                 == BITINT_TYPE)))
        return t;
     }
   if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
--- a/gcc/cp/cvt.cc     2026-11-06 18:32:41.070465857 +0100
+++ b/gcc/cp/cvt.cc     2026-11-11 13:16:41.828958331 +0100
@@ -1868,6 +1868,7 @@ build_expr_type_conversion (int desires,
     switch (TREE_CODE (basetype))
       {
       case INTEGER_TYPE:
+      case BITINT_TYPE:
        if ((desires & WANT_NULL) && null_ptr_cst_p (expr))
          return expr;
        /* fall through.  */
@@ -1897,6 +1898,7 @@ build_expr_type_conversion (int desires,
        switch (TREE_CODE (TREE_TYPE (basetype)))
          {
          case INTEGER_TYPE:
+         case BITINT_TYPE:
          case BOOLEAN_TYPE:
            return (desires & WANT_INT) ? expr : NULL_TREE;
          case ENUMERAL_TYPE:
@@ -1937,6 +1939,7 @@ build_expr_type_conversion (int desires,
        {
        case BOOLEAN_TYPE:
        case INTEGER_TYPE:
+       case BITINT_TYPE:
          win = (desires & WANT_INT); break;
        case ENUMERAL_TYPE:
          win = (desires & WANT_ENUM); break;
--- a/gcc/cp/init.cc    2026-11-06 18:32:41.072465831 +0100
+++ b/gcc/cp/init.cc    2026-11-11 13:16:41.829680586 +0100
@@ -4930,6 +4930,7 @@ build_vec_init (tree base, tree maxindex
            {
              if (digested
                  && (TREE_CODE (type) == INTEGER_TYPE
+                     || TREE_CODE (type) == BITINT_TYPE
                      || is_byte_access_type (type))
                  && TYPE_PRECISION (type) == CHAR_BIT)
                {
--- a/gcc/cp/mangle.cc  2026-11-11 10:28:33.749006561 +0100
+++ b/gcc/cp/mangle.cc  2026-11-11 13:16:41.830167880 +0100
@@ -2554,7 +2554,8 @@ write_type (tree type)
              if (!VOID_TYPE_P (type)
                  && TREE_CODE (type) != INTEGER_TYPE
                  && TREE_CODE (type) != REAL_TYPE
-                 && TREE_CODE (type) != BOOLEAN_TYPE)
+                 && TREE_CODE (type) != BOOLEAN_TYPE
+                 && TREE_CODE (type) != BITINT_TYPE)
                add_substitution (type);
              return;
            }
@@ -2566,6 +2567,7 @@ write_type (tree type)
            case INTEGER_TYPE:  /* Includes wchar_t.  */
            case REAL_TYPE:
            case FIXED_POINT_TYPE:
+           case BITINT_TYPE:
              {
                /* If this is a typedef, TYPE may not be one of
                   the standard builtin type nodes, but an alias of one.  Use
@@ -2940,7 +2942,16 @@ write_CV_qualifiers_for_type (const tree
                    ::= f   # float
                    ::= d   # double
                    ::= e   # long double, __float80
-                   ::= g   # __float128          [not supported]
+                   ::= g   # __float128
+                   ::= Di  # char32_t
+                   ::= Ds  # char16_t
+                   ::= Du  # char8_t
+                   ::= DB <number> _ # C++29 signed _BitInt(N)
+                   ::= DB <instantiation-dependent expression> _
+                                     # C++29 signed _BitInt(N)
+                   ::= DU <number> _ # C++29 unsigned _BitInt(N)
+                   ::= DU <instantiation-dependent expression> _
+                                     # C++29 unsigned _BitInt(N)
                    ::= u <source-name>  # vendor extended type */
 
 static void
@@ -3056,6 +3067,18 @@ write_builtin_type (tree type)
        gcc_unreachable ();
       break;
 
+    case BITINT_TYPE:
+      if (TYPE_UNSIGNED (type))
+       write_string ("DU");
+      else
+       write_string ("DB");
+      if (TYPE_PRECISION (type) != 0)
+       write_number (TYPE_PRECISION (type), /*unsigned_p=*/1, 10);
+      else
+       write_expression (BITINT_PREC (type));
+      write_char ('_');
+      break;
+
     default:
       gcc_unreachable ();
     }
--- a/gcc/cp/class.cc   2026-11-11 10:28:33.745006614 +0100
+++ b/gcc/cp/class.cc   2026-11-11 13:16:41.830820812 +0100
@@ -7316,9 +7316,13 @@ layout_class_type (tree t, tree *virtual
          width = tree_to_uhwi (DECL_SIZE (field));
          if (width != TYPE_PRECISION (ftype))
            {
-             TREE_TYPE (field)
-               = c_build_bitfield_integer_type (width,
-                                                TYPE_UNSIGNED (ftype));
+             if (BITINT_TYPE_P (ftype) && width >= 1)
+               TREE_TYPE (field)
+                 = build_bitint_type (width, TYPE_UNSIGNED (ftype));
+             else
+               TREE_TYPE (field)
+                 = c_build_bitfield_integer_type (width,
+                                                  TYPE_UNSIGNED (ftype));
              TREE_TYPE (field)
                = cp_build_qualified_type (TREE_TYPE (field),
                                           cp_type_quals (ftype));
@@ -7374,7 +7378,8 @@ layout_class_type (tree t, tree *virtual
             to that width.  */
          && (DECL_SIZE (field) == NULL_TREE
              || integer_zerop (DECL_SIZE (field)))
-         && TREE_TYPE (field) != error_mark_node)
+         && TREE_TYPE (field) != error_mark_node
+         && DECL_BIT_FIELD (field))
        SET_DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field, 1);
       check_non_pod_aggregate (field);
     }
--- a/gcc/cp/module.cc  2026-11-11 10:28:33.751006535 +0100
+++ b/gcc/cp/module.cc  2026-11-12 10:31:26.357957754 +0100
@@ -9801,6 +9801,17 @@ trees_out::type_node (tree type)
        }
       break;
 
+    case BITINT_TYPE:
+      tree_node (BITINT_PREC (type));
+      if (streaming_p ())
+       {
+         unsigned prec = TYPE_PRECISION (type);
+         bool unsigned_p = TYPE_UNSIGNED (type);
+
+         u ((prec << 1) | unsigned_p);
+       }
+      break;
+
     case METHOD_TYPE:
     case FUNCTION_TYPE:
       {
@@ -10611,6 +10622,26 @@ trees_in::tree_node (bool is_use)
              }
            break;
 
+         case BITINT_TYPE:
+           {
+             tree prec = tree_node ();
+             unsigned enc = u ();
+             if (!get_overrun ())
+               {
+                 if ((enc & ~1) != 0)
+                   res = build_bitint_type (enc >> 1, enc & 1);
+                 else
+                   {
+                     res = make_node (BITINT_TYPE);
+                     TYPE_PRECISION (res) = 0;
+                     TYPE_UNSIGNED (res) = enc & 1;
+                     BITINT_PREC (res) = prec;
+                     SET_TYPE_STRUCTURAL_EQUALITY (res);
+                   }
+               }
+           }
+           break;
+
          case FUNCTION_TYPE:
          case METHOD_TYPE:
            {
--- a/gcc/testsuite/c-c++-common/builtin-bswapg-1.c     2026-11-06 
18:32:41.086465643 +0100
+++ b/gcc/testsuite/c-c++-common/builtin-bswapg-1.c     2026-11-11 
13:16:41.834809766 +0100
@@ -1,6 +1,7 @@
 /* Test __builtin_bswapg.  */
 /* { dg-do run { target { c || c++11 } } } */
 /* { dg-options "-O2" } */
+/* { dg-additional-options "-Wno-c++29-extensions" { target c++26_down } } */
 
 #if !__has_builtin(__builtin_bswapg)
 #error __builtin_bswapg unsupported
--- a/gcc/testsuite/c-c++-common/builtin-bswapg-3.c     2026-11-06 
18:32:41.086465643 +0100
+++ b/gcc/testsuite/c-c++-common/builtin-bswapg-3.c     2026-11-11 
13:16:41.834960406 +0100
@@ -1,6 +1,7 @@
 /* Test __builtin_bswapg.  */
 /* { dg-do compile } */
 /* { dg-options "" } */
+/* { dg-additional-options "-Wno-c++29-extensions" { target c++26_down } } */
 
 int
 main ()
--- a/gcc/testsuite/c-c++-common/builtin-bitreverseg-1.c        2026-11-06 
18:32:41.086465643 +0100
+++ b/gcc/testsuite/c-c++-common/builtin-bitreverseg-1.c        2026-11-11 
13:16:41.835152040 +0100
@@ -1,6 +1,7 @@
 /* Test __builtin_bitreverseg.  */
 /* { dg-do run { target { c || c++11 } } } */
 /* { dg-options "-O2" } */
+/* { dg-additional-options "-Wno-c++29-extensions" { target c++26_down } } */
 
 #if !__has_builtin(__builtin_bitreverseg)
 #error __builtin_bitreverseg unsupported
--- a/gcc/testsuite/g++.dg/ext/bitint1.C        2026-11-06 18:32:41.087465629 
+0100
+++ b/gcc/testsuite/g++.dg/ext/bitint1.C        2026-11-11 13:16:41.831287099 
+0100
@@ -1,9 +0,0 @@
-// PR c/102989
-// { dg-do compile }
-
-_BitInt(63) a;                 // { dg-error "expected" }
-unsigned _BitInt(31) b;                // { dg-error "expected" }
-int c = 21wb;                  // { dg-error "invalid suffix 'wb' on integer 
constant" "" { target c++98_only } }
-                               // { dg-error "unable to find numeric literal 
operator 'operator\"\"wb'" "" { target c++11 } .-1 }
-long long d = 60594869054uwb;  // { dg-error "invalid suffix 'uwb' on integer 
constant" "" { target c++98_only } }
-                               // { dg-error "unable to find numeric literal 
operator 'operator\"\"uwb'" "" { target c++11 } .-1 }
--- a/gcc/testsuite/g++.dg/ext/bitint2.C        2026-11-06 18:32:41.087465629 
+0100
+++ b/gcc/testsuite/g++.dg/ext/bitint2.C        2026-11-11 13:16:41.831476601 
+0100
@@ -1,10 +0,0 @@
-// PR c/102989
-// { dg-do compile }
-// { dg-options "" }
-
-_BitInt(63) a;                 // { dg-error "expected" }
-unsigned _BitInt(31) b;                // { dg-error "expected" }
-int c = 21wb;                  // { dg-error "invalid suffix 'wb' on integer 
constant" "" { target c++98_only } }
-                               // { dg-error "unable to find numeric literal 
operator 'operator\"\"wb'" "" { target c++11 } .-1 }
-long long d = 60594869054uwb;  // { dg-error "invalid suffix 'uwb' on integer 
constant" "" { target c++98_only } }
-                               // { dg-error "unable to find numeric literal 
operator 'operator\"\"uwb'" "" { target c++11 } .-1 }
--- a/gcc/testsuite/g++.dg/ext/bitint3.C        2026-11-06 18:32:41.087465629 
+0100
+++ b/gcc/testsuite/g++.dg/ext/bitint3.C        2026-11-11 13:16:41.831612286 
+0100
@@ -1,8 +0,0 @@
-// PR c/102989
-// { dg-do compile { target c++11 } }
-
-constexpr int operator""wb (unsigned long long) { return 0; }  // { dg-warning 
"reserved for future standardization" }
-constexpr int operator""uwb (unsigned long long) { return 1; } // { dg-warning 
"reserved for future standardization" }
-
-static_assert (-42wb == 0, "");
-static_assert (81uwb == 1, "");
--- a/gcc/testsuite/g++.dg/ext/bitint4.C        2026-11-06 18:32:41.087465629 
+0100
+++ b/gcc/testsuite/g++.dg/ext/bitint4.C        2026-11-11 13:16:41.831718996 
+0100
@@ -1,9 +0,0 @@
-// PR c/102989
-// { dg-do compile { target c++11 } }
-// { dg-options "" }
-
-constexpr int operator""wb (unsigned long long) { return 0; }  // { dg-warning 
"reserved for future standardization" }
-constexpr int operator""uwb (unsigned long long) { return 1; } // { dg-warning 
"reserved for future standardization" }
-
-static_assert (-42wb == 0, "");
-static_assert (81uwb == 1, "");
--- a/gcc/testsuite/g++.dg/cpp29/bitint1.C      2026-11-11 13:16:41.831941083 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint1.C      2026-11-11 13:16:41.831941083 
+0100
@@ -0,0 +1,27 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+void
+foo (int x)
+{
+  _BitInt (1) a;
+  signed _BitInt (1) b;
+  _BitInt (0) c;               // { dg-error "'_BitInt' argument '0' is not a 
positive integer constant expression" }
+  unsigned _BitInt (0) d;      // { dg-error "'_BitInt' argument '0' is not a 
positive integer constant expression" }
+  _BitInt (-42) e;             // { dg-error "narrowing conversion of '-42' 
from 'int' to '\[^'\n\r]*'" }
+  _BitInt (-5) unsigned f;     // { dg-error "narrowing conversion of '-5' 
from 'int' to '\[^'\n\r]*'" }
+  _BitInt (4294967295ULL) g;   // { dg-error "'_BitInt' argument '4294967295' 
is larger than 'BITINT_MAXWIDTH' '\[0-9]+'" }
+  long _BitInt (42) h;         // { dg-error "'long' specified with 
'_BitInt\\\(42\\\)'" }
+  long long _BitInt (42) i;    // { dg-error "'long long' specified with 
'_BitInt\\\(42\\\)'" }
+  _BitInt (42) long j;         // { dg-error "'long' specified with 
'_BitInt\\\(42\\\)'" }
+  _BitInt (42) long long k;    // { dg-error "'long long' specified with 
'_BitInt\\\(42\\\)'" }
+  short _BitInt (42) l;                // { dg-error "'short' specified with 
'_BitInt\\\(42\\\)'" }
+  _BitInt (42) short m;                // { dg-error "'short' specified with 
'_BitInt\\\(42\\\)'" }
+  _Complex _BitInt (42) n;     // { dg-error "complex invalid for 'n'" }
+  _BitInt (42) _Complex o;     // { dg-error "complex invalid for 'o'" }
+  int _BitInt (42) p;          // { dg-error "two or more data types in 
declaration of 'p'" }
+  _BitInt (42) int q;          // { dg-error "two or more data types in 
declaration of 'q'" }
+  _BitInt (x) r;               // { dg-error "'x' is not a constant 
expression" }
+}                              // { dg-error "'_BitInt' argument is not an 
integer constant expression" "" { target *-*-* } .-1 }
--- a/gcc/testsuite/g++.dg/cpp29/bitint2.C      2026-11-11 13:16:41.832037162 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint2.C      2026-11-11 13:16:41.832037162 
+0100
@@ -0,0 +1,9 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target bitint }
+
+auto a = 123wb;                // { dg-error "'wb' literal suffixes before 
C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+auto b = 234uwb;       // { dg-error "'wb' literal suffixes before C\\\+\\\+29 
are a GCC extension" "" { target c++26_down } }
+_BitInt(1) c;          // { dg-error "'_BitInt' only available with" "" { 
target c++26_down } }
+unsigned _BitInt(1) d; // { dg-error "'_BitInt' only available with" "" { 
target c++26_down } }
+_BitInt(1) signed e;   // { dg-error "'_BitInt' only available with" "" { 
target c++26_down } }
--- a/gcc/testsuite/g++.dg/cpp29/bitint3.C      2026-11-11 13:16:41.832122509 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint3.C      2026-11-11 14:38:50.982574598 
+0100
@@ -0,0 +1,10 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile }
+// { dg-options "" }
+// { dg-require-effective-target bitint }
+
+int a = 123wb;
+unsigned b = 234uwb;
+_BitInt(1) c;
+unsigned _BitInt(1) d;
+_BitInt(1) signed e;
--- a/gcc/testsuite/g++.dg/cpp29/bitint4.C      2026-11-11 13:16:41.832201891 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint4.C      2026-11-11 13:16:41.832201891 
+0100
@@ -0,0 +1,10 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic" }
+// { dg-require-effective-target bitint }
+
+auto a = 123wb;                // { dg-warning "'wb' literal suffixes before 
C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+auto b = 234uwb;       // { dg-warning "'wb' literal suffixes before 
C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+_BitInt(1) c;          // { dg-warning "'_BitInt' only available with" "" { 
target c++26_down } }
+unsigned _BitInt(1) d; // { dg-warning "'_BitInt' only available with" "" { 
target c++26_down } }
+_BitInt(1) signed e;   // { dg-warning "'_BitInt' only available with" "" { 
target c++26_down } }
--- a/gcc/testsuite/g++.dg/cpp29/bitint5.C      2026-11-11 13:16:41.832290516 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint5.C      2026-11-11 13:16:41.832290516 
+0100
@@ -0,0 +1,128 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+template <class, class>
+struct same_type { static constexpr bool value = false; };
+template <class T>
+struct same_type <T, T> { static constexpr bool value = true; };
+
+#define expr_has_type(e, t) same_type <decltype (e), t>::value
+
+#ifdef __BITINT_MAXWIDTH__
+void
+foo (void)
+{
+  _BitInt(42) a = (_BitInt(42)) 1;
+  _BitInt(42) unsigned b = (unsigned _BitInt(42)) 2;
+  _BitInt(5) c = (_BitInt(5)) 3;
+  _BitInt(5) unsigned d = (unsigned _BitInt(5)) 4;
+  _BitInt(32) e = (_BitInt(32)) 5;
+  _BitInt(32) unsigned f = (unsigned _BitInt(32)) 6;
+  constexpr int g = 43;
+  enum E { F = 44 };
+  _BitInt(g) h;
+  unsigned _BitInt(F) i;
+  static_assert (expr_has_type (a, signed _BitInt(42)), "");
+  static_assert (expr_has_type (a, _BitInt(42)), "");
+  static_assert (!expr_has_type (a, unsigned _BitInt(42)), "");
+  static_assert (!expr_has_type (b, signed _BitInt(42)), "");
+  static_assert (!expr_has_type (b, _BitInt(42)), "");
+  static_assert (expr_has_type (b, unsigned _BitInt(42)), "");
+  static_assert (expr_has_type (a + b, unsigned _BitInt(42)), "");
+  static_assert (expr_has_type (a * b, unsigned _BitInt(42)), "");
+  static_assert (expr_has_type (a - b, unsigned _BitInt(42)), "");
+  static_assert (expr_has_type (a * a, _BitInt(42)), "");
+  static_assert (expr_has_type (a / b, unsigned _BitInt(42)), "");
+  static_assert (expr_has_type (c, signed _BitInt(5)), "");
+  static_assert (expr_has_type (c, _BitInt(5)), "");
+  static_assert (!expr_has_type (c, unsigned _BitInt(5)), "");
+  static_assert (!expr_has_type (d, signed _BitInt(5)), "");
+  static_assert (!expr_has_type (d, _BitInt(5)), "");
+  static_assert (expr_has_type (d, unsigned _BitInt(5)), "");
+  static_assert (expr_has_type (c + d, unsigned _BitInt(5)), "");
+  static_assert (expr_has_type (c * d, unsigned _BitInt(5)), "");
+  static_assert (expr_has_type (c - d, unsigned _BitInt(5)), "");
+  static_assert (expr_has_type (c * c, _BitInt(5)), "");
+  static_assert (expr_has_type (c / d, unsigned _BitInt(5)), "");
+  static_assert (expr_has_type (e, signed _BitInt(32)), "");
+  static_assert (expr_has_type (e, _BitInt(32)), "");
+  static_assert (!expr_has_type (e, unsigned _BitInt(32)), "");
+  static_assert (!expr_has_type (f, signed _BitInt(32)), "");
+  static_assert (!expr_has_type (f, _BitInt(32)), "");
+  static_assert (expr_has_type (f, unsigned _BitInt(32)), "");
+  static_assert (expr_has_type (e + f, unsigned _BitInt(32)), "");
+  static_assert (expr_has_type (e * f, unsigned _BitInt(32)), "");
+  static_assert (expr_has_type (e - f, unsigned _BitInt(32)), "");
+  static_assert (expr_has_type (e * e, _BitInt(32)), "");
+  static_assert (expr_has_type (e / f, unsigned _BitInt(32)), "");
+#if __CHAR_BIT__ * __SIZEOF_INT__ == 32
+  static_assert (expr_has_type (e + 1, int), "");
+  static_assert (expr_has_type (f + 1, unsigned int), "");
+  static_assert (expr_has_type (e + 1U, unsigned int), "");
+  static_assert (expr_has_type (f + 1U, unsigned int), "");
+  static_assert (expr_has_type (1 - e, int), "");
+  static_assert (expr_has_type (1 - f, unsigned int), "");
+  static_assert (expr_has_type (1U * e, unsigned int), "");
+  static_assert (expr_has_type (1U / f, unsigned int), "");
+#endif
+  static_assert (expr_has_type (0wb, _BitInt(1)), "");
+  static_assert (expr_has_type (-1WB, _BitInt(2)), "");
+  static_assert (expr_has_type (-1wb - 1wb, _BitInt(2)), "");
+  static_assert (expr_has_type (1wb, _BitInt(2)), "");
+  static_assert (expr_has_type (2wb, _BitInt(3)), "");
+  static_assert (expr_has_type (0wbu, unsigned _BitInt(1)), "");
+  static_assert (expr_has_type (-1UWB, unsigned _BitInt(1)), "");
+  static_assert (expr_has_type (1uWB, unsigned _BitInt(1)), "");
+  static_assert (expr_has_type (2Uwb, unsigned _BitInt(2)), "");
+  static_assert (expr_has_type (h, signed _BitInt(43)), "");
+  static_assert (expr_has_type (i, unsigned _BitInt(44)), "");
+  static_assert (0wb == 0, "");
+  static_assert (-1wb == -1, "");
+  static_assert (0xffffffffwb == 4294967295wb, "");
+  static_assert (0xffffffffwb == 000000000000000000000000000037777777777wb, 
"");
+  static_assert (0x0000000000000000000000000ffffffffwb == 
0b00011111111111111111111111111111111wb, "");
+#if __BITINT_MAXWIDTH__ >= 128
+  static_assert (expr_has_type (0xffffffffffffffffffffffffffffffffuwb, 
unsigned _BitInt(128)), "");
+  static_assert (0xffffffffffffffffffffffffffffffffuwb == 
340282366920938463463374607431768211455uwb, "");
+  static_assert (200000000000000000000000000000000000000wb == 
0x96769950b50d88f41314448000000000WB, "");
+  static_assert (02263551452055206610750114242110000000000000wb == 
200000000000000000000000000000000000000wb, "");
+#endif
+#if __BITINT_MAXWIDTH__ >= 575
+  static_assert (expr_has_type 
(123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567UWB,
 unsigned _BitInt(575)), "");
+  static_assert (expr_has_type 
(0x00000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwbu,
 unsigned _BitInt(575)), "");
+  static_assert (expr_has_type 
(0377777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777uwb,
 unsigned _BitInt(575)), "");
+  static_assert 
(123665200736552267030251260509823595017565674550605919957031528046448612553265933585158200530621522494798835713008069669675682517153375604983773077550946583958303386074349567uwb
 == 
0x00000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwbu,
 "");
+  static_assert 
(0377777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777WBU
 == 
0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffuWB,
 "");
+  static_assert 
(100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000uwb
 == 
0X678159610903F7974A7CB3F22F01FA5D9A2CD6039DE4A7A60F713676CE7D7113FF1A499D9BFD0FDCD2999652EB4C7F398DE2A0000000000000000000000000000000000000000000UWB,
 "");
+  static_assert (expr_has_type 
(-61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb,
 _BitInt(575)), "");
+  static_assert (expr_has_type 
(0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwb,
 signed _BitInt(575)), "");
+  static_assert (expr_has_type 
(0177777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777wb,
 _BitInt(575)), "");
+  static_assert 
(-61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783WB
 == 
-0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwb,
 "");
+  static_assert 
(0177777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777wb
 / 2wb * 2wb + 1wb == 
0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffwb,
 "");
+#endif
+#if (0wb != 0) || (0wbU != 0U) || (1wb != 1) || (1uWB != 1u) \
+    || (-1wb >= 0) || (-1UWB < 0) || (4294967295uwb != 4294967295U) \
+    || 18446744073709551615wbu != 18446744073709551615ULL
+#error ""
+#endif
+}
+
+void
+bar (void)
+{
+  _BitInt(2) a = (_BitInt(2)) 1;
+  unsigned _BitInt(1) b = 1uwb;
+  _BitInt(4) c;
+  c = 7;
+  _BitInt(2) d = 1;
+  _BitInt(5) e = 2wb;
+  unsigned _BitInt(6) f = 3uwb;
+}
+#endif
+
+int
+main ()
+{
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint6.C      2026-11-11 13:16:41.832438752 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint6.C      2026-11-11 13:16:41.832438752 
+0100
@@ -0,0 +1,110 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+using size_t = decltype (sizeof 0);
+template <class, class>
+struct same_type { static constexpr bool value = false; };
+template <class T>
+struct same_type <T, T> { static constexpr bool value = true; };
+template <class>
+struct is_bitint { static constexpr bool value = false; };
+template <size_t N>
+struct is_bitint <_BitInt (N)> { static constexpr bool value = true; };
+template <size_t N>
+struct is_bitint <unsigned _BitInt (N)> { static constexpr bool value = true; 
};
+
+template <int N>
+constexpr int foo (_BitInt (N)) { return N; }
+template <size_t N>
+constexpr int bar (unsigned _BitInt (N)) { return N; }
+template <size_t N>
+constexpr int baz (_BitInt (N)) { return -int (N); }
+template <size_t N>
+constexpr int baz (unsigned _BitInt (N)) { return N; }
+#if __cplusplus >= 201703L
+template <typename T, T N>
+constexpr T qux (_BitInt (N)) { return N; }
+#endif
+#if __cpp_concepts >= 202002L
+template <typename T>
+static constexpr bool is_bitintc_v = requires { baz (T ()); };
+#endif
+
+static_assert (foo (0wb) == 1, "");
+static_assert (foo (1wb) == 2, "");
+static_assert (foo (78262296091114787wb) == 58, "");
+static_assert (bar (0uwb) == 1, "");
+static_assert (bar (1uwb) == 1, "");
+static_assert (bar (2uwb) == 2, "");
+static_assert (bar (78262296091114787uwb) == 57, "");
+static_assert (baz (0wb) == -1, "");
+static_assert (baz (1wb) == -2, "");
+static_assert (baz (78262296091114787wb) == -58, "");
+static_assert (baz (0uwb) == 1, "");
+static_assert (baz (1uwb) == 1, "");
+static_assert (baz (2uwb) == 2, "");
+static_assert (baz (78262296091114787uwb) == 57, "");
+#if __cplusplus >= 201703L
+static_assert (same_type <decltype (qux (0wb)), size_t>::value, "");
+static_assert (qux (68796wb) == 18, "");
+#endif
+static_assert (foo <42> (0) == 42, "");
+static_assert (bar <42> (0) == 42, "");
+template <size_t N>
+struct S { using T = unsigned _BitInt(N); };
+static_assert (same_type <S <42>::T, unsigned _BitInt (42)>::value, "");
+char *p;
+static_assert (is_bitint <decltype (0wb)>::value, "");
+static_assert (is_bitint <decltype (0uwb)>::value, "");
+static_assert (is_bitint <decltype (78262296091114787wb)>::value, "");
+static_assert (is_bitint <decltype (78262296091114787uwb)>::value, "");
+static_assert (!is_bitint <decltype (0)>::value, "");
+static_assert (is_bitint <_BitInt (5)>::value, "");
+static_assert (is_bitint <_BitInt (5) unsigned>::value, "");
+static_assert (is_bitint <_BitInt (__BITINT_MAXWIDTH__) signed>::value, "");
+static_assert (is_bitint <unsigned _BitInt (__BITINT_MAXWIDTH__)>::value, "");
+static_assert (!is_bitint <size_t>::value, "");
+static_assert (!is_bitint <decltype (p - p)>::value, "");
+static_assert (!is_bitint <char>::value, "");
+static_assert (!is_bitint <signed char>::value, "");
+static_assert (!is_bitint <unsigned char>::value, "");
+static_assert (!is_bitint <short>::value, "");
+static_assert (!is_bitint <unsigned short>::value, "");
+static_assert (!is_bitint <int>::value, "");
+static_assert (!is_bitint <unsigned int>::value, "");
+static_assert (!is_bitint <long>::value, "");
+static_assert (!is_bitint <unsigned long>::value, "");
+static_assert (!is_bitint <long long>::value, "");
+static_assert (!is_bitint <unsigned long long>::value, "");
+static_assert (!is_bitint <float>::value, "");
+static_assert (!is_bitint <double>::value, "");
+static_assert (!is_bitint <long double>::value, "");
+#if __cpp_concepts >= 202002L
+static_assert (is_bitintc_v <decltype (0wb)>);
+static_assert (is_bitintc_v <decltype (0uwb)>);
+static_assert (is_bitintc_v <decltype (78262296091114787wb)>);
+static_assert (is_bitintc_v <decltype (78262296091114787uwb)>);
+static_assert (!is_bitintc_v <decltype (0)>);
+static_assert (is_bitintc_v <_BitInt (5)>);
+static_assert (is_bitintc_v <_BitInt (5) unsigned>);
+static_assert (is_bitintc_v <_BitInt (__BITINT_MAXWIDTH__) signed>);
+static_assert (is_bitintc_v <unsigned _BitInt (__BITINT_MAXWIDTH__)>);
+static_assert (!is_bitintc_v <size_t>);
+static_assert (!is_bitintc_v <decltype (p - p)>);
+static_assert (!is_bitintc_v <char>);
+static_assert (!is_bitintc_v <signed char>);
+static_assert (!is_bitintc_v <unsigned char>);
+static_assert (!is_bitintc_v <short>);
+static_assert (!is_bitintc_v <unsigned short>);
+static_assert (!is_bitintc_v <int>);
+static_assert (!is_bitintc_v <unsigned int>);
+static_assert (!is_bitintc_v <long>);
+static_assert (!is_bitintc_v <unsigned long>);
+static_assert (!is_bitintc_v <long long>);
+static_assert (!is_bitintc_v <unsigned long long>);
+static_assert (!is_bitintc_v <float>);
+static_assert (!is_bitintc_v <double>);
+static_assert (!is_bitintc_v <long double>);
+#endif
--- a/gcc/testsuite/g++.dg/cpp29/bitint7.C      2026-11-11 13:16:41.832549371 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint7.C      2026-11-11 13:16:41.832549371 
+0100
@@ -0,0 +1,24 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+using size_t = decltype (sizeof 0);
+
+template <int N>
+void foo (_BitInt (N));                        // { dg-error "'_BitInt' 
argument '0' is not a positive integer constant expression" }
+                                       // { dg-error "'_BitInt' argument 
'\[0-9]*' is larger than 'BITINT_MAXWIDTH' '\[0-9]*'" "" { target *-*-* } .-1 }
+template <size_t N>
+void bar (_BitInt (N + 1));
+
+void
+baz ()
+{
+  foo <0> (0);                         // { dg-error "no matching function for 
call to 'foo<0>\\\(int\\\)'" }
+  foo <1> (0);
+  foo <__BITINT_MAXWIDTH__> (0);
+  foo <__BITINT_MAXWIDTH__ + 1> (0);   // { dg-error "no matching function for 
call to 'foo<\\\(\[0-9]* \\\+ 1\\\)>\\\(int\\\)'" }
+  bar <26> (0);
+  bar (123456789wb);                   // { dg-error "no matching function for 
call to 'bar\\\(_BitInt\\\(28\\\)\\\)'" }
+  bar <27> (123456789wb);
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint8.C      2026-11-11 13:16:41.832638393 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint8.C      2026-11-11 13:16:41.832638393 
+0100
@@ -0,0 +1,54 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+using size_t = decltype (sizeof 0);
+template <class, class>
+struct same_type { static constexpr bool value = false; };
+template <class T>
+struct same_type <T, T> { static constexpr bool value = true; };
+template <class>
+struct is_bitint { static constexpr bool value = false; };
+template <size_t N>
+struct is_bitint <_BitInt (N)> { static constexpr bool value = true; };
+template <size_t N>
+struct is_bitint <unsigned _BitInt (N)> { static constexpr bool value = true; 
};
+
+enum A { A0 = 0wb, A1 = 1wb, A2 = same_type <decltype (A1), _BitInt(2)>::value 
+ 2wb - 1wb,
+        A3 = 3wb, A4, A5 = (5wb + same_type <decltype (A4), _BitInt(3)>::value
+                            + same_type <decltype (A4), _BitInt(4)>::value
+                            + is_bitint <decltype (A4)>::value
+                            + same_type <decltype (A4), unsigned 
_BitInt(3)>::value),
+        A6 = 6wb, A7, A8 = 8wb - 1 + same_type <decltype (A7), 
_BitInt(4)>::value } a;
+constexpr int intprec = __SIZEOF_INT__ * __CHAR_BIT__;
+constexpr int longprec = __SIZEOF_LONG__ * __CHAR_BIT__;
+enum B { B0 = 0, B1 = _BitInt (intprec + 1) (1) << (intprec - 1) } b;
+enum C { C0 = -1wb, C1 = _BitInt (intprec + 1) (1) << (intprec - 1) } c;
+enum D { D0 = 0, D1 = _BitInt (longprec + 1) (1) << (longprec - 1) } d;
+enum E : _BitInt(5) { E0 = 0wb, E1 = 15wb, E2 = _BitInt (46) (2),
+                     E3 = same_type <decltype (E2), _BitInt(5)>::value,
+                     E4 = -15wb - 1 } e;
+enum F { F0 = E0, F1 = same_type <decltype (F0), _BitInt(5)>::value };
+static_assert (same_type <decltype (+a), int>::value, "");
+static_assert (same_type <decltype (a), A>::value, "");
+static_assert (!same_type <decltype (A0), _BitInt (1)>::value, "");
+static_assert (!same_type <decltype (A0), _BitInt (2)>::value, "");
+static_assert (!is_bitint <decltype (A0)>::value, "");
+static_assert (!is_bitint <decltype (+A0)>::value, "");
+static_assert (A2 == 2, "");
+static_assert (A5 == 5, "");
+static_assert (A8 == 8, "");
+static_assert (same_type <decltype (+b), unsigned>::value, "");
+#if __SIZEOF_INT__ == __SIZEOF_LONG__
+static_assert (same_type <decltype (+c), long long>::value, "");
+static_assert (same_type <decltype (+d), unsigned>::value, "");
+#else
+static_assert (same_type <decltype (+c), long>::value, "");
+static_assert (same_type <decltype (+d), unsigned long>::value, "");
+#endif
+static_assert (same_type <decltype (+e), _BitInt(5)>::value, "");
+static_assert (E3 == 1, "");
+#if 0 // FIXME - CWG1765 unimplemented
+static_assert (F1 == 1, "");
+#endif
--- a/gcc/testsuite/g++.dg/cpp29/bitint9.C      2026-11-11 13:16:41.832734044 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint9.C      2026-11-11 13:16:41.832734044 
+0100
@@ -0,0 +1,6 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+#include "../../gcc.dg/bitint-3.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint10.C     2026-11-11 13:16:41.832830291 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint10.C     2026-11-11 13:16:41.832830291 
+0100
@@ -0,0 +1,5 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++29 } }
+// { dg-require-effective-target bitint }
+
+#include "../../gcc.dg/bitint-4.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint11.C     2026-11-11 13:16:41.832915200 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint11.C     2026-11-11 13:16:41.832915200 
+0100
@@ -0,0 +1,6 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+#include "../../gcc.dg/bitint-5.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint12.C     2026-11-11 13:16:41.833002195 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint12.C     2026-11-11 13:16:41.833002195 
+0100
@@ -0,0 +1,5 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++29 } }
+// { dg-require-effective-target bitint }
+
+#include "../../gcc.dg/bitint-6.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint13.C     2026-11-11 13:16:41.833083750 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint13.C     2026-11-11 13:16:41.833083750 
+0100
@@ -0,0 +1,6 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions -w" }
+// { dg-require-effective-target bitint }
+
+#include "../../gcc.dg/bitint-12.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint14.C     2026-11-11 13:16:41.833162460 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint14.C     2026-11-11 13:16:41.833162460 
+0100
@@ -0,0 +1,11 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target { c++29 && bitint575 } } }
+// { dg-options "-pedantic-errors" }
+
+enum A : _BitInt(15) { A0 = 0, A1 = 1 };
+enum B : unsigned _BitInt(575) { B0 = 0, B1 = 1 };
+enum C { C0 = 459875743wb, C1 = 3298437354uwb };
+enum D { D0 = 
61832600368276133515125630254911797508782837275302959978515764023224306276632966792579100265310761247399417856504034834837841258576687802491886538775473291979151693037174783wb,
 D1 };
+// { dg-error "no integral type can represent all of the enumerator values for 
'D'" "" { target *-*-* } .-1 } */
+// { dg-error "overflow in enumeration values" "" { target *-*-* } .-2 } */
+// { dg-warning "unsigned conversion from '_BitInt\\\(575\\\)' to '\[^'\n\r]*' 
changes value from" "" { target *-*-* } .-3 } */
--- a/gcc/testsuite/g++.dg/cpp29/bitint15.C     2026-11-11 13:16:41.833250685 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint15.C     2026-11-11 13:16:41.833250685 
+0100
@@ -0,0 +1,53 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+template <class, class>
+struct same_type { static constexpr bool value = false; };
+template <class T>
+struct same_type <T, T> { static constexpr bool value = true; };
+
+#define expr_has_type(e, t) same_type <decltype (e), t>::value
+
+struct S1 { char x; char : 0; char y; };
+struct S2 { char x; int : 0; char y; };
+#if __BITINT_MAXWIDTH__ >= 575
+struct S3 { char x; _BitInt(575) : 0; char y; };
+#endif
+#if __BITINT_MAXWIDTH__ >= 389
+struct S4 { char x; _BitInt(195) a : 63; _BitInt(282) b : 280; _BitInt(389) c 
: 23; _BitInt(2) d : 1; char y; };
+#endif
+#if __BITINT_MAXWIDTH__ >= 192
+struct S5 { char x; _BitInt(192) a : 191; unsigned _BitInt(192) b : 190; 
_BitInt(192) c : 189; char y; };
+#endif
+struct S6 { _BitInt(2) a : 1; };
+#if __BITINT_MAXWIDTH__ >= 389
+struct S4 s4;
+static_assert (expr_has_type (s4.a + 1uwb, _BitInt(195)));
+static_assert (expr_has_type (s4.b + 1uwb, _BitInt(282)));
+static_assert (expr_has_type (s4.c + 1uwb, _BitInt(389)));
+static_assert (expr_has_type (s4.d * 0wb, _BitInt(2)));
+#endif
+#if __BITINT_MAXWIDTH__ >= 192
+struct S5 s5;
+static_assert (expr_has_type (s5.a + 1uwb, _BitInt(192)));
+static_assert (expr_has_type (s5.b + 1wb, unsigned _BitInt(192)));
+static_assert (expr_has_type (s5.c + 1uwb, _BitInt(192)));
+#endif
+struct S6 s6;
+static_assert (expr_has_type (s6.a + 0wb, _BitInt(2)));
+#if defined(__x86_64__) && __LP64__ && __BITINT_MAXWIDTH__ >= 575
+static_assert (sizeof (struct S1) == 2);
+static_assert (sizeof (struct S2) == 5);
+static_assert (sizeof (struct S3) == 9);
+static_assert (sizeof (struct S4) == 48);
+static_assert (sizeof (struct S5) == 88);
+static_assert (sizeof (struct S6) == 1);
+static_assert (alignof (struct S1) == 1);
+static_assert (alignof (struct S2) == 1);
+static_assert (alignof (struct S3) == 1);
+static_assert (alignof (struct S4) == 8);
+static_assert (alignof (struct S5) == 8);
+static_assert (alignof (struct S6) == 1);
+#endif
--- a/gcc/testsuite/g++.dg/cpp29/bitint16.C     2026-11-11 13:16:41.833354998 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint16.C     2026-11-11 13:16:41.833354998 
+0100
@@ -0,0 +1,22 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+template <class, class>
+struct same_type { static constexpr bool value = false; };
+template <class T>
+struct same_type <T, T> { static constexpr bool value = true; };
+
+#define expr_has_type(e, t) same_type <decltype (e), t>::value
+
+void
+foo (_Complex int ci, _Complex long long cl)
+{
+  _BitInt(__SIZEOF_INT__ * __CHAR_BIT__ - 1) bi = 0wb;
+  _BitInt(__SIZEOF_LONG_LONG__ * __CHAR_BIT__ - 1) bl = 0wb;
+  static_assert (expr_has_type (ci + bi, _Complex int), "");
+  static_assert (expr_has_type (cl + bl, _Complex long long), "");
+  static_assert (expr_has_type (bi + ci, _Complex int), "");
+  static_assert (expr_has_type (bl + cl, _Complex long long), "");
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint17.C     2026-11-11 13:16:41.833442105 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint17.C     2026-11-11 13:16:41.833442105 
+0100
@@ -0,0 +1,17 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+void
+foo (_Complex int ci, _Complex long long cl)
+{
+  _BitInt(__SIZEOF_INT__ * __CHAR_BIT__ + 1) bi = 0wb;
+  ci + bi;                     /* { dg-message "unsupported" } */
+  bi + ci;                     /* { dg-message "unsupported" } */
+#if __BITINT_MAXWIDTH__ >= 575
+  _BitInt(575) bw = 0wb;
+  cl + bw;                     /* { dg-message "unsupported" "" { target 
bitint575 } } */
+  bw + cl;                     /* { dg-message "unsupported" "" { target 
bitint575 } } */
+#endif
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint18.C     2026-11-11 13:16:41.833526023 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint18.C     2026-11-11 13:16:41.833526023 
+0100
@@ -0,0 +1,12 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+#define IB __SIZEOF_INT__ * __CHAR_BIT__
+typedef _BitInt(IB) V1 __attribute__((vector_size (sizeof (_BitInt(IB)))));    
        /* { dg-error "invalid vector type for attribute 'vector_size'" } */
+typedef _BitInt(IB) V2 __attribute__((vector_size (8 * sizeof 
(_BitInt(IB)))));                /* { dg-error "invalid vector type for 
attribute 'vector_size'" } */
+#if __BITINT_MAXWIDTH__ >= 575
+typedef _BitInt(575) V3 __attribute__((vector_size (sizeof (_BitInt(575)))));  
        /* { dg-error "invalid vector type for attribute 'vector_size'" "" { 
target bitint575 } } */
+typedef _BitInt(575) V3 __attribute__((vector_size (16 * sizeof 
(_BitInt(575)))));     /* { dg-error "invalid vector type for attribute 
'vector_size'" "" { target bitint575 } } */
+#endif
--- a/gcc/testsuite/g++.dg/cpp29/bitint19.C     2026-11-11 13:16:41.833624475 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint19.C     2026-11-11 13:16:41.833624475 
+0100
@@ -0,0 +1,18 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target bitint }
+
+_BitInt(63) a;                                 // { dg-error "'_BitInt' only 
available with" "" { target c++26_down } }
+signed _BitInt(15) b;                          // { dg-error "'_BitInt' only 
available with" "" { target c++26_down } }
+unsigned _BitInt(31) c;                                // { dg-error 
"'_BitInt' only available with" "" { target c++26_down } }
+int d = 21wb;                                  // { dg-error "'wb' literal 
suffixes before C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+long long e = 60594869054uwb;                  // { dg-error "'wb' literal 
suffixes before C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+__extension__ _BitInt(63) f;
+__extension__ _BitInt(15) g;
+__extension__ unsigned _BitInt(31) h;
+int i = __extension__ 21wb;                    // { dg-error "'wb' literal 
suffixes before C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+long long j = __extension__ 60594869054uwb;    // { dg-error "'wb' literal 
suffixes before C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+#if 0wb == 0                                   // { dg-error "'wb' literal 
suffixes before C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+#endif
+#if 0uwb == 0                                  // { dg-error "'wb' literal 
suffixes before C\\\+\\\+29 are a GCC extension" "" { target c++26_down } }
+#endif
--- a/gcc/testsuite/g++.dg/cpp29/bitint20.C     2026-11-11 13:16:41.833711112 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint20.C     2026-11-11 13:16:41.833711112 
+0100
@@ -0,0 +1,8 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-add-options ieee } */
+
+#include "../../gcc.dg/bitint-28.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint21.C     2026-11-11 13:16:41.833791476 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint21.C     2026-11-11 13:16:41.833791476 
+0100
@@ -0,0 +1,8 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-add-options ieee } */
+
+#include "../../gcc.dg/bitint-29.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint22.C     2026-11-11 13:16:41.833870879 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint22.C     2026-11-11 13:16:41.833870879 
+0100
@@ -0,0 +1,8 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-add-options ieee } */
+
+#include "../../gcc.dg/bitint-30.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint23.C     2026-11-11 13:16:41.833960275 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint23.C     2026-11-11 13:16:41.833960275 
+0100
@@ -0,0 +1,8 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-add-options ieee } */
+
+#include "../../gcc.dg/bitint-31.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint24.C     2026-11-11 13:16:41.834043270 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint24.C     2026-11-11 13:16:41.834043270 
+0100
@@ -0,0 +1,6 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions -funsigned-bitfields -Wno-overflow" }
+// { dg-require-effective-target bitint }
+
+#include "../../gcc.dg/bitint-34.c"
--- a/gcc/testsuite/g++.dg/cpp29/bitint25.C     2026-11-11 13:16:41.834125892 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint25.C     2026-11-11 13:16:41.834125892 
+0100
@@ -0,0 +1,102 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+#if __BITINT_MAXWIDTH__ >= 156
+struct S156 { unsigned _BitInt(156) a : 135; _BitInt(156) b : 2; };
+struct S156 s1 = { 18071796389618321960417503813958783219759uwb, 0 };
+struct S156 s2 = { 18071796389618321960417503813958783219759uwb, -1 };
+struct T156 { _BitInt(156) a : 2; unsigned _BitInt(156) b : 135; _BitInt(156) 
c : 2; };
+struct T156 s3 = { -1, 10623570996611319062233232245276988766900uwb, -1 };
+struct T156 s4 = { 0, 10623570996611319062233232245276988766900uwb, 0 };
+#endif
+#if __BITINT_MAXWIDTH__ >= 230
+struct U230 { _BitInt(230) a : 140, b : 140, c : 168; unsigned _BitInt(230) d 
: 135; _BitInt(230) e : 2; };
+struct U230 s5 = { -1, -1, 
-167793869854583920719725244652254633450201662238868wb, (unsigned _BitInt(135)) 
-1, -1 };
+struct U230 s6 = { 0, 0, 
-167793869854583920719725244652254633450201662238868wb, 0, 0 };
+#endif
+#if __BITINT_MAXWIDTH__ >= 412
+struct S412 { unsigned _BitInt(412) a : 391; _BitInt(412) b : 2; };
+struct S412 s7 = { 
3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb,
 0 };
+struct S412 s8 = { 
3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb,
 -1 };
+struct T412 { _BitInt(412) a : 2; unsigned _BitInt(412) b : 391; _BitInt(412) 
c : 2; };
+struct T412 s9 = { -1, 
4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb,
 -1 };
+struct T412 s10 = { 0, 
4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb,
 0 };
+#endif
+#if __BITINT_MAXWIDTH__ >= 486
+struct U486 { _BitInt(486) a : 396, b : 396, c : 424; unsigned _BitInt(486) d 
: 391; _BitInt(486) e : 2; };
+struct U486 s11 = { -1, -1, 
-13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb,
 (unsigned _BitInt(391)) -1, -1 };
+struct U486 s12 = { 0, 0, 
13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb,
 0, 0 };
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 156
+__attribute__((noipa)) _BitInt(156)
+f1 (struct S156 *p)
+{
+  return p->a;
+}
+
+__attribute__((noipa)) _BitInt(156)
+f2 (struct T156 *q)
+{
+  return q->b;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 230
+__attribute__((noipa)) _BitInt(230)
+f3 (struct U230 *q)
+{
+  return q->c;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 412
+__attribute__((noipa)) _BitInt(412)
+f4 (struct S412 *p)
+{
+  return p->a;
+}
+#endif
+
+#if __BITINT_MAXWIDTH__ >= 486
+__attribute__((noipa)) _BitInt(412)
+f5 (struct T412 *q)
+{
+  return q->b;
+}
+
+__attribute__((noipa)) _BitInt(486)
+f6 (struct U486 *q)
+{
+  return q->c;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 156
+  if (f1 (&s1) != 18071796389618321960417503813958783219759wb
+      || f1 (&s2) != 18071796389618321960417503813958783219759wb
+      || f2 (&s3) != 10623570996611319062233232245276988766900wb
+      || f2 (&s4) != 10623570996611319062233232245276988766900wb
+#if __BITINT_MAXWIDTH__ >= 230
+      || f3 (&s5) != -167793869854583920719725244652254633450201662238868wb
+      || f3 (&s6) != -167793869854583920719725244652254633450201662238868wb
+#if __BITINT_MAXWIDTH__ >= 412
+      || f4 (&s7) != 
3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb
+      || f4 (&s8) != 
3345867579074605921998363891622879168820794533140203757607077179689806177940265164723139484043689737118576518770430659uwb
+      || f5 (&s9) != 
4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb
+      || f5 (&s10) != 
4349534826165161048611343533362431993802129027379695873644854753645283352804798649538744513979417539155427766538864041uwb
+#if __BITINT_MAXWIDTH__ >= 486
+      || f6 (&s11) != 
-13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb
+      || f6 (&s12) != 
13261086392773587186244717277670203234755842300010780483040284280064790949739084884446379147987979627678541509279207301027482398wb
+#endif
+#endif
+#endif
+      || 0)
+    __builtin_abort ();
+#endif
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint26.C     2026-11-11 13:16:41.834233294 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint26.C     2026-11-11 13:16:41.834233294 
+0100
@@ -0,0 +1,174 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+#if __BITINT_MAXWIDTH__ >= 2048
+struct S { unsigned _BitInt(2048) a : 2048, b : 2048, c : 17, d : 1984, e : 
47; };
+
+__attribute__((noipa)) void
+foo (struct S *p, unsigned _BitInt(1024) x, unsigned _BitInt(1024) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+bar (struct S *p, _BitInt(1024) x, _BitInt(1024) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+baz (struct S *p, unsigned _BitInt(1920) x, unsigned _BitInt(1920) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+qux (struct S *p, _BitInt(1920) x, _BitInt(1920) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+corge (struct S *p, unsigned _BitInt(1900) x, unsigned _BitInt(1900) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+garply (struct S *p, _BitInt(1900) x, _BitInt(1900) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+freddy (struct S *p, unsigned _BitInt(1856) x, unsigned _BitInt(1856) y)
+{
+  p->d = x + y;
+}
+
+__attribute__((noipa)) void
+waldo (struct S *p, _BitInt(1856) x, _BitInt(1856) y)
+{
+  p->d = x + y;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 2048
+  static struct S a = {
+    (unsigned _BitInt(2048)) -1, (unsigned _BitInt(2048)) -1, 0,
+    
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb,
+    0 };
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  foo (&a, 
104931473307998568376284944455816272419276290777426540227909077072607565781305910683656824567560123753706639375583615231475830225655977968417978331508801616912246729932071770026909197561252489929164753507156163716727743848177523298403504040861948797263925263359073704810875557925737265337616304489108966376158uwb,
+       
59920243355458337710161417863366293718453205838526168844643867766614610356796955200643446741760592218738700475637131838188996966576023003439875232851999584726009865342375796439481941924864368246882381830388251975603959739534065212652254710711469239923127731536814696621712112440700123429434845131596418309393uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1024)) 
(104931473307998568376284944455816272419276290777426540227909077072607565781305910683656824567560123753706639375583615231475830225655977968417978331508801616912246729932071770026909197561252489929164753507156163716727743848177523298403504040861948797263925263359073704810875557925737265337616304489108966376158uwb
+                                         + 
59920243355458337710161417863366293718453205838526168844643867766614610356796955200643446741760592218738700475637131838188996966576023003439875232851999584726009865342375796439481941924864368246882381830388251975603959739534065212652254710711469239923127731536814696621712112440700123429434845131596418309393uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  bar (&a, 
57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb,
+       
-72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) 
(57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb
+                                         - 
72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  bar (&a, 
-57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb,
+       
72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) 
(-57696900052508731507403549405758598034300143658103207319023779669222605350088754701899236130746881446668609696540074847952256437939432895408791375123523927312623997545422223335393957708478037810305856074599089747771505132758755976367296302409566647338223622914274236998855494169815473992397952258483243021302wb
+                                         + 
72842517138334828284807942772540307802590837121353434029836391595120471219334627505967145432766876195584374614127318095866715782180696170716375533225237916165551049842450106822314457638403968810895466326295894575989547864175819099455892706907142084137837126096115084189997686278911334555694779991889737914097wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  baz (&a, 
10046674427769604624104256297198144686571499244626667928387309298929376098027029576279399593953275611749179759608292175423884771453122373428446900092238297028886595955833507301142748242755116804512085361142982476735378897659094772516348752033708523603210976749488948779512595019051543682808058468854071972247830133684340816736701518783450117953852153823310129790997309466493287853621568286299778852505115809372004493209067461371542082762075506285274124778581566591915544298148128752861519967454244034597718098760883258950102015993032472578845214796865351706334956028690073732824uwb,
+       
30612973315144170166058778463435127763223804285434461900113576569307167284342964585999954156672087142162949891238018140546663093988389394093653346239026903138243323723125156926788354976614671206441524235029939884520999076249737807760807371468017378301855151655697275608111727393644387426955142126548487675753916845926686394733479586127697929204917657250622879488360082650822591661695896650131839942739510727482535722456341390110272939230980001298487239399637003898555616301235680415285050104075063794523896618439667653475267312346144285918918555551560640876816454019806981149346uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1920)) 
(10046674427769604624104256297198144686571499244626667928387309298929376098027029576279399593953275611749179759608292175423884771453122373428446900092238297028886595955833507301142748242755116804512085361142982476735378897659094772516348752033708523603210976749488948779512595019051543682808058468854071972247830133684340816736701518783450117953852153823310129790997309466493287853621568286299778852505115809372004493209067461371542082762075506285274124778581566591915544298148128752861519967454244034597718098760883258950102015993032472578845214796865351706334956028690073732824uwb
+                                         + 
30612973315144170166058778463435127763223804285434461900113576569307167284342964585999954156672087142162949891238018140546663093988389394093653346239026903138243323723125156926788354976614671206441524235029939884520999076249737807760807371468017378301855151655697275608111727393644387426955142126548487675753916845926686394733479586127697929204917657250622879488360082650822591661695896650131839942739510727482535722456341390110272939230980001298487239399637003898555616301235680415285050104075063794523896618439667653475267312346144285918918555551560640876816454019806981149346uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  qux (&a, 
13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb,
+       
-28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) 
(13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb
+                                         - 
28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  qux (&a, 
-13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb,
+       
28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) 
(-13016013079173103291099614189980806323842381205278317530930273134000041840366629398775140035115843810473709567772778302693082141789947769432915075175055773162235275161483274294215337459035077170772792870300959580270341613989326562524225424508425190735941052267862958598262374659588227320019762607908610630268016655402141784434304726674259917365365145444188910006023308330624708207712990521956652004155313903306577312390098183139445953080974727140041686581923442658014291404592915933601121276930660194063673671653456001711834226809501680465040298012239797363611423758621282776913wb
+                                         + 
28446813692377976500941113458061042520266991028095510595278491516213231833343127954947958697833886839482306777092401391414122947073667300047514166155274861575977000665767593771951017640475352507402509527609607984675986413277164234921816991523476344394719439798762757430434241059844235758595109405173122010749636425151730743690113153472777458440898097338588818905573968955113497483813484624809156428527476374283821364764837699711517717561791530220504756111060769224676146577608338385717008304034083639716040512354106392262091939683382939797913585450175899702396573011461697333034wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  corge (&a, 
64171754625068989919140837000994640111727112880534508544592426680368730902810558177004927067680584241787685314155807083650755609249723856651964519183899537071234738837290542998681042547778311707239561819724556440611184192044964070498288365795284868545819938858772217225078359446215623326392822749370924397592547178151227397770818626413099911326742674650698762654686406157275035696691347162817031065585247142657560604671730554635740625725423122837711895800895711658181231623745755808749163225238686251279789200140461667130974133295022126714627199940806900473151584805415195uwb,
+        
10507418314822331271773044775475398971761862686484059883353388622395900044257992245406697831431608445492518374055670273513238951235394317339987011165612885709605626614512380143227176716397144020233730021138060515517588833982427087228530305874044854732163307726421040484981309646463788817170356084893284995027973314236302612849097075836350102359164874937708745757469764621885202447442513857862352391464614086255770773793956362777147243363233935961477956934790795000772957425970578395645388729306937175617548119494347932433902865451670299375626936811709188316328877711066266uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1900)) 
(64171754625068989919140837000994640111727112880534508544592426680368730902810558177004927067680584241787685314155807083650755609249723856651964519183899537071234738837290542998681042547778311707239561819724556440611184192044964070498288365795284868545819938858772217225078359446215623326392822749370924397592547178151227397770818626413099911326742674650698762654686406157275035696691347162817031065585247142657560604671730554635740625725423122837711895800895711658181231623745755808749163225238686251279789200140461667130974133295022126714627199940806900473151584805415195uwb
+                                         + 
10507418314822331271773044775475398971761862686484059883353388622395900044257992245406697831431608445492518374055670273513238951235394317339987011165612885709605626614512380143227176716397144020233730021138060515517588833982427087228530305874044854732163307726421040484981309646463788817170356084893284995027973314236302612849097075836350102359164874937708745757469764621885202447442513857862352391464614086255770773793956362777147243363233935961477956934790795000772957425970578395645388729306937175617548119494347932433902865451670299375626936811709188316328877711066266uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  garply (&a, 
5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb,
+         
-11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) 
(5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb
+                                         - 
11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  garply (&a, 
-5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb,
+         
11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) 
(-5868498364266506524577605439874476245426686973426700959109780040518579902459120222835694740563157202759355683256866704897404738166990697509006899291520655587106188792963812978958796524525114633868734394698171505881029257971723149816101834255875674028498733002531852425394712442344661593840806267795078353686464213122490607069539130187483435521707186417019607510065332996787510980236995794693748424754247983911372699143281367405983607540070016093272958998509389591623580441329207441967951990849359776649279644251163115935521494220792988120247084691082546041345346792010242wb
+                                         + 
11347197387388289958753680375659873990863802565165926783885510745013060725984194141674849668356803935504502347397858539486502925095461636911844100666788607295568532884580882894109301976999229938210427880195738078809053637249087573583682429867587279531387832617988923148433372488547498087660777174110005800619288934623468273334771375199931835359341800380427942391213375221877238129575165007900737487381149085076124736500637930425093008055570334609463897282935446073021835731133748226290709813024590427968994174853094349555317945926316079817123209552512780636562105208387802wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  freddy (&a, 
469252210556625900395321429768118373804271568886989705934619437372829749132450328525095591418777876663202724364753274041797120201435942727547992144282707964490547818365755687730365454828375134854279482853064804665151021915981446605629215712706942096964289300397645214217794960755102650152979365923262599694610536124094997394321315947501858977257060703103733108840085012396782596975471783978125423726167181925777731261440167038194119207611413091278559852866397229440000783332669637577092646062124696818736270717467013532501981408774198349957822434112647379005uwb,
+         
94070362846521859801705045906377514499678063439381376804210675777018147620560698746550277910632595473262065531986582027530889487288929548537551849350646108895807918918852446632833846575499156686904909401606895792588697611268444788607535104014712049735819470354574164068246431532229132503353457795214808974265484177085433521985873683760061889599206572475727862420333264989214721uwb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1856)) 
(469252210556625900395321429768118373804271568886989705934619437372829749132450328525095591418777876663202724364753274041797120201435942727547992144282707964490547818365755687730365454828375134854279482853064804665151021915981446605629215712706942096964289300397645214217794960755102650152979365923262599694610536124094997394321315947501858977257060703103733108840085012396782596975471783978125423726167181925777731261440167038194119207611413091278559852866397229440000783332669637577092646062124696818736270717467013532501981408774198349957822434112647379005uwb
+                                         + 
94070362846521859801705045906377514499678063439381376804210675777018147620560698746550277910632595473262065531986582027530889487288929548537551849350646108895807918918852446632833846575499156686904909401606895792588697611268444788607535104014712049735819470354574164068246431532229132503353457795214808974265484177085433521985873683760061889599206572475727862420333264989214721uwb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+  a.c = 0; a.e = 0;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  waldo (&a, 
1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb,
+        
-1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb);
+  if (a.c != 0
+      || a.d != (unsigned _BitInt(1984)) 
(1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb
+                                         - 
1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb)
+      || a.e != 0)
+    __builtin_abort ();
+  a.c = (unsigned _BitInt(17)) -1; a.e = (unsigned _BitInt(47)) -1;
+  a.d = 
463917970028583783130221282302564969130016367896792751313667391101541961539304534496983866855440713410002431069759936351630526612549721249569957606098639059197777177066032356317311377246348044640151413769734055367388430457406812743413172658955449268511488689032363320539418931719008983635641503449973939023326362877468919468283037515857633928783609142892025498615118950347461620276675520332352617645525539262850089419854851129987768363578088495582892780293031963532530279743528517338149433293940566560543044220727331056862486476880117725416278405160480429664896200335164399009026428547582688918275uwb;
+  waldo (&a, 
-1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb,
+        
1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb);
+  if (a.c != (unsigned _BitInt(17)) -1
+      || a.d != (unsigned _BitInt(1984)) 
(-1077348803036394846628052386931031477092268876025321812336873307109206087913752615224874421161444982772998789879219858386748806555972198085260006113906211122468615028890545260489793232067037450746579377138953792376873515309768581358563731155642172915978701005830989320122620476563103717896150506580888344726125553209010077521592754225575655834325745455132336873236702283266289571810538207635029653566169955010183651423213982024692540900019767542204779117227674016120820660909981982885062591878726323250427606511922288639386683242905759109753373254316490315520wb
+                                         + 
1985135610193680083664291948423326826338570203155603158942205167041487273165308445801199835862136626921357451386015509681859914819637185970790210070511326605854081763286684508027882510126294034064385106397322907046379158342618996640895074355907730050734884021065120984859890403437402777612953035357875244537844302334232817294878831239344832373356172440988052876809100011735694217824097948414358681171509506376373643145643902181072431032225879081947415698025494088413669737484685311564937312541325716542256136502054579138572508697290597615704140203423671499131wb)
+      || a.e != (unsigned _BitInt(47)) -1)
+    __builtin_abort ();
+#endif
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint27.C     2026-11-11 13:16:41.834502872 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint27.C     2026-11-11 13:16:41.834502872 
+0100
@@ -0,0 +1,179 @@
+// P3666R5 - Bit-precise integers
+// { dg-do run { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+template <class, class>
+struct same_type { static constexpr bool value = false; };
+template <class T>
+struct same_type <T, T> { static constexpr bool value = true; };
+
+#define expr_has_type(e, t) same_type <decltype (e), t>::value
+
+void
+foo ()
+{
+  _BitInt(1) a = (_BitInt(1)) -1;
+  static_assert (expr_has_type (a, signed _BitInt(1)), "");
+  static_assert (expr_has_type (0wb, _BitInt(1)), "");
+  static_assert (expr_has_type (~0wb, _BitInt(1)), "");
+  static_assert (expr_has_type (1wb, _BitInt(2)), "");
+  static_assert (expr_has_type (-1wb, _BitInt(2)), "");
+  static_assert (expr_has_type (2wb, _BitInt(3)), "");
+  static_assert (expr_has_type (0wb + 0wb, signed _BitInt(1)), "");
+  static_assert (expr_has_type (0wb + 0uwb, unsigned _BitInt(1)), "");
+  static_assert (expr_has_type (0wb + 1wb, _BitInt(2)), "");
+  static_assert (expr_has_type (0uwb + 0wb, unsigned _BitInt(1)), "");
+  static_assert (expr_has_type (1wb + 0wb, _BitInt(2)), "");
+  static_assert (0wb == 0, "");
+  static_assert (~0wb == -1, "");
+  static_assert (~~0wb == 0, "");
+  static_assert (-1wb == -1, "");
+}
+
+_BitInt(1) b = 0wb;
+_BitInt(1) c = ~0wb;
+_BitInt(1) d = 0wb;
+
+[[gnu::noipa]] void
+bar (_BitInt(1) a[21], signed _BitInt(1) b[21], const _BitInt(1) c[21])
+{
+  a[0] = b[0] + c[0];
+  a[1] = b[1] + c[1];
+  a[2] = b[2] + c[2];
+  a[3] = b[3] - c[3];
+  a[4] = b[4] - c[4];
+  a[5] = b[5] - c[5];
+  a[6] = b[6] * c[6];
+  a[7] = b[7] * c[7];
+  a[8] = b[8] * c[8];
+  a[9] = b[9] / c[9];
+  a[10] = b[10] % c[10];
+  a[11] = b[10] % c[11];
+  a[12] = b[12] & c[12];
+  a[13] = b[13] & c[13];
+  a[14] = b[14] & c[14];
+  a[15] = b[15] | c[15];
+  a[16] = b[16] | c[16];
+  a[17] = b[17] | c[17];
+  a[18] = b[18] ^ c[18];
+  a[19] = b[19] ^ c[19];
+  a[20] = b[20] ^ c[20];
+}
+
+#if __BITINT_MAXWIDTH__ >= 256
+[[gnu::noipa]] _BitInt(256)
+baz (_BitInt(256) x, _BitInt(1) y)
+{
+  return x * y;
+}
+#endif
+
+[[gnu::noipa]] void
+qux (_BitInt(1) p[3], float q, double r, long double s)
+{
+  p[0] = q;
+  p[1] = r;
+  p[2] = s;
+}
+
+[[gnu::noipa]] void
+corge (_BitInt(1) p[2], float q[2], double r[2], long double s[2])
+{
+  q[0] = p[0];
+  q[1] = p[1];
+  r[0] = p[0];
+  r[1] = p[1];
+  s[0] = p[0];
+  s[1] = p[1];
+}
+
+int
+main ()
+{
+  if (b != 0 || c != -1)
+    __builtin_abort ();
+  if (0)
+    {
+      --b;
+      ++c;
+    }
+  else
+    {
+      b += _BitInt(1)(-1wb);
+      c -= _BitInt(1)(-1wb);
+    }
+  if (b != -1 || c != 0)
+    __builtin_abort ();
+  b = ~b;
+  c = ~c;
+  if (b != 0 || c != -1)
+    __builtin_abort ();
+  c *= d;
+  if (d != 0)
+    __builtin_abort ();
+  _BitInt(1) e[21];
+  _BitInt(1) f[21] = {
+    0, -1, 0,
+    0, -1, -1,
+    0, -1, 0,
+    0,
+    0, -1,
+    0, -1, -1,
+    0, 0, -1,
+    0, -1, -1
+  };
+  signed _BitInt(1) g[21] = {
+    0, 0, -1,
+    0, 0, -1,
+    0, 0, -1,
+    -1,
+    -1, -1,
+    0, 0, -1,
+    0, -1, -1,
+    0, 0, -1
+  }; 
+  bar (e, f, g);
+  _BitInt(1) h[21] = {
+    0, -1, -1,
+    0, -1, 0,
+    0, 0, 0,
+    0,
+    0, 0,
+    0, 0, -1,
+    0, -1, -1,
+    0, -1, 0
+  };
+  for (int i = 0; i < 21; ++i)
+    if (e[i] != h[i])
+      __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 256
+  if (baz 
(24807048826655379640613156875228202584070386120119745959437529938064756141700wb,
 ~0wb)
+      != 
-24807048826655379640613156875228202584070386120119745959437529938064756141700wb)
+    __builtin_abort ();
+  if (baz 
(24807048826655379640613156875228202584070386120119745959437529938064756141700wb,
 0wb) != 0wb)
+    __builtin_abort ();
+  if (baz 
(-24807048826655379640613156875228202584070386120119745959437529938064756141700wb,
 0wb) != 0wb)
+    __builtin_abort ();
+  if (baz (0wb, ~0wb) != 0wb)
+    __builtin_abort ();
+#endif
+  qux (e, 0.5f, 0.25, 0.75L);
+  qux (e + 3, -0.5f, -0.25, -0.75L);
+  qux (e + 6, 0.f, 0., 0.L);
+  qux (e + 9, -1.f, -1., -1.L);
+  qux (e + 12, -1.5f, -1.25, -1.75L);
+  for (int i = 0; i < 15; ++i)
+    if (e[i] != (i < 9 ? 0 : -1))
+      __builtin_abort ();
+  e[0] = 0wb;
+  e[1] = ~0wb;
+  float j[2];
+  double k[2];
+  long double l[2];
+  corge (e, j, k, l);
+  if (j[0] != 0.0f || j[1] != -1.0f
+      || k[0] != 0.0 || k[1] != -1.0
+      || l[0] != 0.0L || l[1] != -1.0L)
+    __builtin_abort ();
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint28.C     2026-11-11 14:04:05.637614277 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint28.C     2026-11-11 14:04:05.637614277 
+0100
@@ -0,0 +1,19 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+template <int N> struct A { void foo (_BitInt(N)); };
+template <int N> void A <N>::foo (_BitInt(N)) {}       // { dg-bogus "no 
declaration matches" }
+
+template <int N> struct B { static _BitInt(N) m; };
+template <int N> _BitInt(N) B <N>::m;                  // { dg-bogus 
"conflicting declaration" }
+
+template <int N> void bar (_BitInt(N));
+template <int N> void bar (_BitInt(N));
+
+int
+main ()
+{
+  bar <5> (0wb);                                       // { dg-bogus "call of 
overloaded 'bar<5>\\\(_BitInt\\\(1\\\)\\\)' is ambiguous" }
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint29.C     2026-11-12 19:11:57.151159474 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint29.C     2026-11-12 19:12:23.695810400 
+0100
@@ -0,0 +1,24 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint575 }
+
+unsigned a[42];
+
+unsigned
+foo (unsigned _BitInt (532) x)
+{
+  return a[x];
+}
+
+unsigned
+bar (unsigned *p, unsigned _BitInt (532) x)
+{
+  return p[x];
+}
+
+unsigned long long
+baz (unsigned long long x, _BitInt (575) y)
+{
+  return x << y;
+}
--- a/gcc/testsuite/g++.dg/cpp29/bitint30.C     2026-11-12 20:12:38.301411444 
+0100
+++ b/gcc/testsuite/g++.dg/cpp29/bitint30.C     2026-11-12 20:16:42.865179722 
+0100
@@ -0,0 +1,20 @@
+// P3666R5 - Bit-precise integers
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wno-c++29-extensions" }
+// { dg-require-effective-target bitint }
+
+template <typename T>
+struct S { static constexpr bool v = false; };
+
+template <int N>
+struct S <unsigned _BitInt(N)> { static constexpr bool v = true; };
+
+template <int N>
+constexpr bool
+foo ()
+{
+  return S <unsigned _BitInt(42 > N ? 42 : N)>::v;     // { dg-bogus "template 
argument 1 is invalid" }
+}
+
+static_assert (foo <0> (), "");
+static_assert (foo <64> (), "");
--- a/gcc/testsuite/lib/target-supports.exp     2026-11-11 10:28:33.815005690 
+0100
+++ b/gcc/testsuite/lib/target-supports.exp     2026-11-11 13:16:41.836191933 
+0100
@@ -4721,37 +4721,57 @@ proc check_effective_target_fixed_point
 # Return 1 if the target supports _BitInt(N), 0 otherwise.
 
 proc check_effective_target_bitint { } {
+    if [check_effective_target_c++] {
+       set opts "-std=c++29"
+    } else {
+       set opts "-std=c23"
+    }
     return [check_no_compiler_messages bitint object {
        _BitInt (2) a = 1wb;
        unsigned _BitInt (__BITINT_MAXWIDTH__) b = 0uwb;
-    } "-std=c23"]
+    } $opts]
 }
 
 # Return 1 if the target supports _BitInt(128), 0 otherwise.
 
 proc check_effective_target_bitint128 { } {
+    if [check_effective_target_c++] {
+       set opts "-std=c++29"
+    } else {
+       set opts "-std=c23"
+    }
     return [check_no_compiler_messages bitint128 object {
        _BitInt (2) a = 1wb;
        unsigned _BitInt (128) b = 0uwb;
-    } "-std=c23"]
+    } $opts]
 }
 
 # Return 1 if the target supports _BitInt(575), 0 otherwise.
 
 proc check_effective_target_bitint575 { } {
+    if [check_effective_target_c++] {
+       set opts "-std=c++29"
+    } else {
+       set opts "-std=c23"
+    }
     return [check_no_compiler_messages bitint575 object {
        _BitInt (2) a = 1wb;
        unsigned _BitInt (575) b = 0uwb;
-    } "-std=c23"]
+    } $opts]
 }
 
 # Return 1 if the target supports _BitInt(65535), 0 otherwise.
 
 proc check_effective_target_bitint65535 { } {
+    if [check_effective_target_c++] {
+       set opts "-std=c++29"
+    } else {
+       set opts "-std=c23"
+    }
     return [check_no_compiler_messages bitint65535 object {
        _BitInt (2) a = 1wb;
        unsigned _BitInt (65535) b = 0uwb;
-    } "-std=c23"]
+    } $opts]
 }
 
 # Return 1 if the target supports compiling decimal floating point,
--- a/libcpp/expr.cc    2026-11-06 18:32:41.088465616 +0100
+++ b/libcpp/expr.cc    2026-11-11 14:04:50.046500932 +0100
@@ -386,8 +386,6 @@ interpret_int_suffix (cpp_reader *pfile,
 
   if (wb)
     {
-      if (CPP_OPTION (pfile, cplusplus))
-       return 0;
       if (l > 0 || i > 0 || z > 0)
        return 0;
     }
@@ -897,26 +895,37 @@ cpp_classify_number (cpp_reader *pfile,
                                 virtual_location, 0, message);
        }
 
-      if ((result & CPP_N_BITINT) != 0
-         && CPP_OPTION (pfile, cpp_warn_c11_c23_compat) != 0)
+      if ((result & CPP_N_BITINT) != 0)
        {
-         if (CPP_OPTION (pfile, cpp_warn_c11_c23_compat) > 0)
-           {
-             const char *message = N_("ISO C does not support literal "
-                                      "%<wb%> suffixes before C23");
-             if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, true_false))
-               cpp_pedwarning_with_line (pfile, CPP_W_C11_C23_COMPAT,
-                                         virtual_location, 0, message);
-             else
-               cpp_warning_with_line (pfile, CPP_W_C11_C23_COMPAT,
-                                      virtual_location, 0, message);
-           }
-         else if (!CPP_OPTION (pfile, true_false))
+         if (CPP_OPTION (pfile, cplusplus))
            {
-             const char *message = N_("ISO C does not support literal "
-                                      "%<wb%> suffixes before C23");
-             cpp_pedwarning_with_line (pfile, CPP_W_PEDANTIC,
-                                       virtual_location, 0, message);
+             if (CPP_OPTION (pfile, lang) < CLK_GNUCXX29
+                 && CPP_PEDANTIC (pfile))
+               cpp_pedwarning_with_line (pfile, CPP_W_CXX29_EXTENSIONS,
+                                         virtual_location, 0,
+                                         "%<wb%> literal suffixes before "
+                                         "C++29 are a GCC extension");
+           }
+         else if (CPP_OPTION (pfile, cpp_warn_c11_c23_compat) != 0)
+           {
+             if (CPP_OPTION (pfile, cpp_warn_c11_c23_compat) > 0)
+               {
+                 const char *message = N_("ISO C does not support literal "
+                                          "%<wb%> suffixes before C23");
+                 if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, true_false))
+                   cpp_pedwarning_with_line (pfile, CPP_W_C11_C23_COMPAT,
+                                             virtual_location, 0, message);
+                 else
+                   cpp_warning_with_line (pfile, CPP_W_C11_C23_COMPAT,
+                                          virtual_location, 0, message);
+               }
+             else if (!CPP_OPTION (pfile, true_false))
+               {
+                 const char *message = N_("ISO C does not support literal "
+                                          "%<wb%> suffixes before C23");
+                 cpp_pedwarning_with_line (pfile, CPP_W_PEDANTIC,
+                                           virtual_location, 0, message);
+               }
            }
        }
 

        Jakub

Reply via email to