aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-09-06 17:34:49 +0200
committerJakub Jelinek <jakub@redhat.com>2023-09-06 17:34:49 +0200
commit8c984a1c3693df63520558631c827bb2c2d8b5bc (patch)
tree7b4fbfd8dea2c7820cff7436890ebe353795c43f /gcc/c
parent2ce182e258d3ab11310442d5f4dd1d063018aca9 (diff)
downloadgcc-8c984a1c3693df63520558631c827bb2c2d8b5bc.zip
gcc-8c984a1c3693df63520558631c827bb2c2d8b5bc.tar.gz
gcc-8c984a1c3693df63520558631c827bb2c2d8b5bc.tar.bz2
C _BitInt support [PR102989]
This patch adds the C FE support, c-family support, small libcpp change so that 123wb and 42uwb suffixes are handled plus glimits.h change to define BITINT_MAXWIDTH macro. The previous patches really do nothing without this, which enables all the support. 2023-09-06 Jakub Jelinek <jakub@redhat.com> PR c/102989 gcc/ * glimits.h (BITINT_MAXWIDTH): Define if __BITINT_MAXWIDTH__ is predefined. gcc/c-family/ * c-common.cc (c_common_reswords): Add _BitInt as keyword. (unsafe_conversion_p): Handle BITINT_TYPE like INTEGER_TYPE. (c_common_signed_or_unsigned_type): Handle BITINT_TYPE. (c_common_truthvalue_conversion, c_common_get_alias_set, check_builtin_function_arguments): Handle BITINT_TYPE like INTEGER_TYPE. (sync_resolve_size): Add ORIG_FORMAT argument. If FETCH && !ORIG_FORMAT, type is BITINT_TYPE, return -1 if size isn't one of 1, 2, 4, 8 or 16 or if it is 16 but TImode is not supported. (atomic_bitint_fetch_using_cas_loop): New function. (resolve_overloaded_builtin): Adjust sync_resolve_size caller. If -1 is returned, use atomic_bitint_fetch_using_cas_loop to lower it. Formatting fix. (keyword_begins_type_specifier): Handle RID_BITINT. * c-common.h (enum rid): Add RID_BITINT enumerator. * c-cppbuiltin.cc (c_cpp_builtins): For C call targetm.c.bitint_type_info and predefine __BITINT_MAXWIDTH__ and for -fbuilding-libgcc also __LIBGCC_BITINT_LIMB_WIDTH__ and __LIBGCC_BITINT_ORDER__ macros if _BitInt is supported. * c-lex.cc (interpret_integer): Handle CPP_N_BITINT. * c-pretty-print.cc (c_pretty_printer::simple_type_specifier, c_pretty_printer::direct_abstract_declarator, c_pretty_printer::direct_declarator, c_pretty_printer::declarator): Handle BITINT_TYPE. (pp_c_integer_constant): Handle printing of large precision wide_ints which would buffer overflow digit_buffer. * c-warn.cc (conversion_warning, warnings_for_convert_and_check, warnings_for_convert_and_check): Handle BITINT_TYPE like INTEGER_TYPE. gcc/c/ * c-convert.cc (c_convert): Handle BITINT_TYPE like INTEGER_TYPE. * c-decl.cc (check_bitfield_type_and_width): Allow BITINT_TYPE bit-fields. (finish_struct): Prefer to use BITINT_TYPE for BITINT_TYPE bit-fields if possible. (declspecs_add_type): Formatting fixes. Handle cts_bitint. Adjust for added union in *specs. Handle RID_BITINT. (finish_declspecs): Handle cts_bitint. Adjust for added union in *specs. * c-parser.cc (c_keyword_starts_typename, c_token_starts_declspecs, c_parser_declspecs, c_parser_gnu_attribute_any_word): Handle RID_BITINT. (c_parser_omp_clause_schedule): Handle BITINT_TYPE like INTEGER_TYPE. * c-tree.h (enum c_typespec_keyword): Mention _BitInt in comment. Add cts_bitint enumerator. (struct c_declspecs): Move int_n_idx and floatn_nx_idx into a union and add bitint_prec there as well. * c-typeck.cc (c_common_type, comptypes_internal): Handle BITINT_TYPE. (perform_integral_promotions): Promote BITINT_TYPE bit-fields to their declared type. (build_array_ref, build_unary_op, build_conditional_expr, build_c_cast, convert_for_assignment, digest_init, build_binary_op): Handle BITINT_TYPE. * c-fold.cc (c_fully_fold_internal): Handle BITINT_TYPE like INTEGER_TYPE. * c-aux-info.cc (gen_type): Handle BITINT_TYPE. libcpp/ * expr.cc (interpret_int_suffix): Handle wb and WB suffixes. * include/cpplib.h (CPP_N_BITINT): Define.
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-aux-info.cc11
-rw-r--r--gcc/c/c-convert.cc1
-rw-r--r--gcc/c/c-decl.cc194
-rw-r--r--gcc/c/c-fold.cc14
-rw-r--r--gcc/c/c-parser.cc32
-rw-r--r--gcc/c/c-tree.h18
-rw-r--r--gcc/c/c-typeck.cc147
7 files changed, 308 insertions, 109 deletions
diff --git a/gcc/c/c-aux-info.cc b/gcc/c/c-aux-info.cc
index e33e863..7c1c456 100644
--- a/gcc/c/c-aux-info.cc
+++ b/gcc/c/c-aux-info.cc
@@ -409,6 +409,17 @@ gen_type (const char *ret_val, tree t, formals_style style)
data_type = concat ("unsigned ", data_type, NULL);
break;
+ case BITINT_TYPE:
+ {
+ char buf[sizeof ("2147483647")];
+ sprintf (buf, "%d", TYPE_PRECISION (t));
+ if (TYPE_UNSIGNED (t))
+ data_type = concat ("unsigned _BitInt(", buf, ")", NULL);
+ else
+ data_type = concat ("_BitInt(", buf, ")", NULL);
+ break;
+ }
+
case OPAQUE_TYPE:
case REAL_TYPE:
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
diff --git a/gcc/c/c-convert.cc b/gcc/c/c-convert.cc
index 5754d00..71e618c 100644
--- a/gcc/c/c-convert.cc
+++ b/gcc/c/c-convert.cc
@@ -117,6 +117,7 @@ c_convert (tree type, tree expr, bool init_const)
gcc_fallthrough ();
case INTEGER_TYPE:
+ case BITINT_TYPE:
if (sanitize_flags_p (SANITIZE_FLOAT_CAST)
&& current_function_decl != NULL_TREE
&& SCALAR_FLOAT_TYPE_P (TREE_TYPE (expr))
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index e611d7a..c9dd135 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -6390,7 +6390,8 @@ check_bitfield_type_and_width (location_t loc, tree *type, tree *width,
/* Detect invalid bit-field type. */
if (TREE_CODE (*type) != INTEGER_TYPE
&& TREE_CODE (*type) != BOOLEAN_TYPE
- && TREE_CODE (*type) != ENUMERAL_TYPE)
+ && TREE_CODE (*type) != ENUMERAL_TYPE
+ && TREE_CODE (*type) != BITINT_TYPE)
{
error_at (loc, "bit-field %qs has invalid type", name);
*type = unsigned_type_node;
@@ -9330,8 +9331,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
tree type = TREE_TYPE (field);
if (width != TYPE_PRECISION (type))
{
- TREE_TYPE (field)
- = c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type));
+ if (TREE_CODE (type) == BITINT_TYPE
+ && (width > 1 || TYPE_UNSIGNED (type)))
+ TREE_TYPE (field)
+ = build_bitint_type (width, TYPE_UNSIGNED (type));
+ else
+ TREE_TYPE (field)
+ = c_build_bitfield_integer_type (width,
+ TYPE_UNSIGNED (type));
SET_DECL_MODE (field, TYPE_MODE (TREE_TYPE (field)));
}
DECL_INITIAL (field) = NULL_TREE;
@@ -11546,14 +11553,18 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
("both %<long%> and %<void%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_int_n)
- error_at (loc,
- ("both %<long%> and %<__int%d%> in "
- "declaration specifiers"),
- int_n_data[specs->int_n_idx].bitsize);
+ error_at (loc,
+ ("both %<long%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->u.int_n_idx].bitsize);
else if (specs->typespec_word == cts_bool)
error_at (loc,
("both %<long%> and %<_Bool%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_bitint)
+ error_at (loc,
+ ("both %<long%> and %<_BitInt%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_char)
error_at (loc,
("both %<long%> and %<char%> in "
@@ -11566,8 +11577,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<long%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->typespec_word == cts_dfloat32)
@@ -11606,11 +11617,15 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<short%> and %<__int%d%> in "
"declaration specifiers"),
- int_n_data[specs->int_n_idx].bitsize);
+ int_n_data[specs->u.int_n_idx].bitsize);
else if (specs->typespec_word == cts_bool)
error_at (loc,
("both %<short%> and %<_Bool%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_bitint)
+ error_at (loc,
+ ("both %<short%> and %<_BitInt%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_char)
error_at (loc,
("both %<short%> and %<char%> in "
@@ -11627,8 +11642,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<short%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->typespec_word == cts_dfloat32)
@@ -11679,8 +11694,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<signed%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->typespec_word == cts_dfloat32)
@@ -11731,8 +11746,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<unsigned%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->typespec_word == cts_dfloat32)
@@ -11770,6 +11785,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<complex%> and %<_Bool%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_bitint)
+ error_at (loc,
+ ("both %<complex%> and %<_BitInt%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_dfloat32)
error_at (loc,
("both %<complex%> and %<_Decimal32%> in "
@@ -11809,7 +11828,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<_Sat%> and %<__int%d%> in "
"declaration specifiers"),
- int_n_data[specs->int_n_idx].bitsize);
+ int_n_data[specs->u.int_n_idx].bitsize);
}
else if (specs->typespec_word == cts_auto_type)
error_at (loc,
@@ -11823,6 +11842,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<_Sat%> and %<_Bool%> in "
"declaration specifiers"));
+ else if (specs->typespec_word == cts_bitint)
+ error_at (loc,
+ ("both %<_Sat%> and %<_BitInt%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_char)
error_at (loc,
("both %<_Sat%> and %<char%> in "
@@ -11843,8 +11866,8 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<_Sat%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->typespec_word == cts_dfloat32)
@@ -11882,7 +11905,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
{
/* "void", "_Bool", "char", "int", "float", "double",
"_FloatN", "_FloatNx", "_Decimal32", "__intN",
- "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
+ "_Decimal64", "_Decimal128", "_Fract", "_Accum", "_BitInt(N)" or
"__auto_type". */
if (specs->typespec_word != cts_none)
{
@@ -11927,7 +11950,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
case RID_INT_N_1:
case RID_INT_N_2:
case RID_INT_N_3:
- specs->int_n_idx = i - RID_INT_N_0;
+ specs->u.int_n_idx = i - RID_INT_N_0;
if (!in_system_header_at (input_location)
/* If the INT_N type ends in "__", and so is of the format
"__intN__", don't pedwarn. */
@@ -11935,29 +11958,29 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
+ (IDENTIFIER_LENGTH (type) - 2), "__", 2) != 0))
pedwarn (loc, OPT_Wpedantic,
"ISO C does not support %<__int%d%> types",
- int_n_data[specs->int_n_idx].bitsize);
+ int_n_data[specs->u.int_n_idx].bitsize);
if (specs->long_p)
error_at (loc,
("both %<__int%d%> and %<long%> in "
"declaration specifiers"),
- int_n_data[specs->int_n_idx].bitsize);
+ int_n_data[specs->u.int_n_idx].bitsize);
else if (specs->saturating_p)
error_at (loc,
("both %<_Sat%> and %<__int%d%> in "
"declaration specifiers"),
- int_n_data[specs->int_n_idx].bitsize);
+ int_n_data[specs->u.int_n_idx].bitsize);
else if (specs->short_p)
error_at (loc,
("both %<__int%d%> and %<short%> in "
"declaration specifiers"),
- int_n_data[specs->int_n_idx].bitsize);
- else if (! int_n_enabled_p[specs->int_n_idx])
+ int_n_data[specs->u.int_n_idx].bitsize);
+ else if (! int_n_enabled_p[specs->u.int_n_idx])
{
specs->typespec_word = cts_int_n;
error_at (loc,
"%<__int%d%> is not supported on this target",
- int_n_data[specs->int_n_idx].bitsize);
+ int_n_data[specs->u.int_n_idx].bitsize);
}
else
{
@@ -12115,13 +12138,13 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
}
return specs;
CASE_RID_FLOATN_NX:
- specs->floatn_nx_idx = i - RID_FLOATN_NX_FIRST;
+ specs->u.floatn_nx_idx = i - RID_FLOATN_NX_FIRST;
if (!in_system_header_at (input_location))
pedwarn_c11 (loc, OPT_Wpedantic,
"ISO C does not support the %<_Float%d%s%> type"
" before C2X",
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
@@ -12129,49 +12152,49 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
error_at (loc,
("both %<long%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->short_p)
error_at (loc,
("both %<short%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->signed_p)
error_at (loc,
("both %<signed%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->unsigned_p)
error_at (loc,
("both %<unsigned%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
else if (specs->saturating_p)
error_at (loc,
("both %<_Sat%> and %<_Float%d%s%> in "
"declaration specifiers"),
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
- else if (FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx) == NULL_TREE)
+ else if (FLOATN_NX_TYPE_NODE (specs->u.floatn_nx_idx) == NULL_TREE)
{
specs->typespec_word = cts_floatn_nx;
error_at (loc,
"%<_Float%d%s%> is not supported on this target",
- floatn_nx_types[specs->floatn_nx_idx].n,
- (floatn_nx_types[specs->floatn_nx_idx].extended
+ floatn_nx_types[specs->u.floatn_nx_idx].n,
+ (floatn_nx_types[specs->u.floatn_nx_idx].extended
? "x"
: ""));
}
@@ -12268,6 +12291,63 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
pedwarn (loc, OPT_Wpedantic,
"ISO C does not support fixed-point types");
return specs;
+ case RID_BITINT:
+ if (specs->long_p)
+ error_at (loc,
+ ("both %<long%> and %<_BitInt%> in "
+ "declaration specifiers"));
+ else if (specs->short_p)
+ error_at (loc,
+ ("both %<short%> and %<_BitInt%> in "
+ "declaration specifiers"));
+ else if (specs->complex_p)
+ error_at (loc,
+ ("both %<complex%> and %<_BitInt%> in "
+ "declaration specifiers"));
+ else if (specs->saturating_p)
+ error_at (loc,
+ ("both %<_Sat%> and %<_BitInt%> in "
+ "declaration specifiers"));
+ else
+ {
+ specs->typespec_word = cts_bitint;
+ specs->locations[cdw_typespec] = loc;
+ specs->u.bitint_prec = -1;
+ if (error_operand_p (spec.expr))
+ return specs;
+ if (TREE_CODE (spec.expr) != INTEGER_CST
+ || !INTEGRAL_TYPE_P (TREE_TYPE (spec.expr)))
+ {
+ error_at (loc, "%<_BitInt%> argument is not an integer "
+ "constant expression");
+ return specs;
+ }
+ if (tree_int_cst_sgn (spec.expr) <= 0)
+ {
+ error_at (loc, "%<_BitInt%> argument %qE is not a "
+ "positive integer constant expression",
+ spec.expr);
+ return specs;
+ }
+ if (wi::to_widest (spec.expr) > WIDE_INT_MAX_PRECISION - 1)
+ {
+ error_at (loc, "%<_BitInt%> argument %qE is larger than "
+ "%<BITINT_MAXWIDTH%> %qd",
+ spec.expr, (int) WIDE_INT_MAX_PRECISION - 1);
+ return specs;
+ }
+ specs->u.bitint_prec = tree_to_uhwi (spec.expr);
+ struct bitint_info info;
+ if (!targetm.c.bitint_type_info (specs->u.bitint_prec,
+ &info))
+ {
+ sorry_at (loc, "%<_BitInt(%d)%> is not supported on "
+ "this target", specs->u.bitint_prec);
+ specs->u.bitint_prec = -1;
+ return specs;
+ }
+ }
+ return specs;
default:
/* ObjC reserved word "id", handled below. */
break;
@@ -12669,12 +12749,12 @@ finish_declspecs (struct c_declspecs *specs)
case cts_int_n:
gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
gcc_assert (!(specs->signed_p && specs->unsigned_p));
- if (! int_n_enabled_p[specs->int_n_idx])
+ if (! int_n_enabled_p[specs->u.int_n_idx])
specs->type = integer_type_node;
else
specs->type = (specs->unsigned_p
- ? int_n_trees[specs->int_n_idx].unsigned_type
- : int_n_trees[specs->int_n_idx].signed_type);
+ ? int_n_trees[specs->u.int_n_idx].unsigned_type
+ : int_n_trees[specs->u.int_n_idx].signed_type);
if (specs->complex_p)
{
pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
@@ -12734,12 +12814,12 @@ finish_declspecs (struct c_declspecs *specs)
case cts_floatn_nx:
gcc_assert (!specs->long_p && !specs->short_p
&& !specs->signed_p && !specs->unsigned_p);
- if (FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx) == NULL_TREE)
+ if (FLOATN_NX_TYPE_NODE (specs->u.floatn_nx_idx) == NULL_TREE)
specs->type = integer_type_node;
else if (specs->complex_p)
- specs->type = COMPLEX_FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx);
+ specs->type = COMPLEX_FLOATN_NX_TYPE_NODE (specs->u.floatn_nx_idx);
else
- specs->type = FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx);
+ specs->type = FLOATN_NX_TYPE_NODE (specs->u.floatn_nx_idx);
break;
case cts_dfloat32:
case cts_dfloat64:
@@ -12841,6 +12921,22 @@ finish_declspecs (struct c_declspecs *specs)
: accum_type_node;
}
break;
+ case cts_bitint:
+ gcc_assert (!specs->long_p && !specs->short_p
+ && !specs->complex_p);
+ if (!specs->unsigned_p && specs->u.bitint_prec == 1)
+ {
+ error_at (specs->locations[cdw_typespec],
+ "%<signed _BitInt%> argument must be at least 2");
+ specs->type = integer_type_node;
+ break;
+ }
+ if (specs->u.bitint_prec == -1)
+ specs->type = integer_type_node;
+ else
+ specs->type = build_bitint_type (specs->u.bitint_prec,
+ specs->unsigned_p);
+ break;
default:
gcc_unreachable ();
}
diff --git a/gcc/c/c-fold.cc b/gcc/c/c-fold.cc
index adbade4..15ec795 100644
--- a/gcc/c/c-fold.cc
+++ b/gcc/c/c-fold.cc
@@ -379,7 +379,8 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr);
if (code == LSHIFT_EXPR
&& TREE_CODE (orig_op0) != INTEGER_CST
- && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
&& TREE_CODE (op0) == INTEGER_CST
&& c_inhibit_evaluation_warnings == 0
&& !TYPE_OVERFLOW_WRAPS (TREE_TYPE (orig_op0))
@@ -398,6 +399,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
? G_("left shift count is negative")
: G_("right shift count is negative")));
else if ((TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
|| TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
&& compare_tree_int (op1,
TYPE_PRECISION (TREE_TYPE (orig_op0)))
@@ -418,11 +420,13 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
if (code == LSHIFT_EXPR
/* If either OP0 has been folded to INTEGER_CST... */
&& ((TREE_CODE (orig_op0) != INTEGER_CST
- && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE)
&& TREE_CODE (op0) == INTEGER_CST)
/* ...or if OP1 has been folded to INTEGER_CST... */
|| (TREE_CODE (orig_op1) != INTEGER_CST
- && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
+ && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE)
&& TREE_CODE (op1) == INTEGER_CST))
&& c_inhibit_evaluation_warnings == 0)
/* ...then maybe we can detect an overflow. */
@@ -435,8 +439,10 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
&& TREE_CODE (orig_op1) != INTEGER_CST
&& TREE_CODE (op1) == INTEGER_CST
&& (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op0)) == BITINT_TYPE
|| TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE)
- && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE)
+ && (TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (orig_op1)) == BITINT_TYPE))
warn_for_div_by_zero (loc, op1);
if (code == MEM_REF
&& ret != expr
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index c8d285f..c04962d 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -584,6 +584,7 @@ c_keyword_starts_typename (enum rid keyword)
case RID_DFLOAT128:
CASE_RID_FLOATN_NX:
case RID_BOOL:
+ case RID_BITINT:
case RID_ENUM:
case RID_STRUCT:
case RID_UNION:
@@ -787,6 +788,7 @@ c_token_starts_declspecs (c_token *token)
case RID_DFLOAT128:
CASE_RID_FLOATN_NX:
case RID_BOOL:
+ case RID_BITINT:
case RID_ENUM:
case RID_STRUCT:
case RID_UNION:
@@ -3118,6 +3120,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
_Bool
_Complex
[_Imaginary removed in C99 TC2]
+ _BitInt ( constant-expression )
struct-or-union-specifier
enum-specifier
typedef-name
@@ -3125,6 +3128,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
(_Bool and _Complex are new in C99.)
(atomic-type-specifier is new in C11.)
+ (_BitInt is new in C2X.)
C90 6.5.3, C99 6.7.3, C11 6.7.3:
@@ -3401,6 +3405,30 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
t = c_parser_typeof_specifier (parser);
declspecs_add_type (loc, specs, t);
break;
+ case RID_BITINT:
+ if (!typespec_ok)
+ goto out;
+ else
+ {
+ attrs_ok = true;
+ seen_type = true;
+ t.kind = ctsk_resword;
+ t.spec = c_parser_peek_token (parser)->value;
+ t.expr = error_mark_node;
+ t.expr_const_operands = true;
+ t.has_enum_type_specifier = false;
+ c_parser_consume_token (parser);
+ matching_parens parens;
+ if (parens.require_open (parser))
+ {
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ t.expr = convert_lvalue_to_rvalue (loc, expr, true,
+ true).value;
+ parens.skip_until_found_close (parser);
+ }
+ declspecs_add_type (loc, specs, t);
+ }
+ break;
case RID_ATOMIC:
/* C parser handling of Objective-C constructs needs
checking for correct lvalue-to-rvalue conversions, and
@@ -5049,6 +5077,7 @@ c_parser_gnu_attribute_any_word (c_parser *parser)
case RID_DFLOAT128:
CASE_RID_FLOATN_NX:
case RID_BOOL:
+ case RID_BITINT:
case RID_FRACT:
case RID_ACCUM:
case RID_SAT:
@@ -16308,7 +16337,8 @@ c_parser_omp_clause_schedule (c_parser *parser, tree list)
error_at (here,
"schedule %<auto%> does not take "
"a %<chunk_size%> parameter");
- else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
+ else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
{
/* Attempt to statically determine when the number isn't
positive. */
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 7c5234e..f928137 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -270,7 +270,7 @@ enum c_storage_class {
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
"double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
- or none of these. */
+ "_BitInt", or none of these. */
enum c_typespec_keyword {
cts_none,
cts_void,
@@ -286,6 +286,7 @@ enum c_typespec_keyword {
cts_floatn_nx,
cts_fract,
cts_accum,
+ cts_bitint,
cts_auto_type
};
@@ -366,11 +367,16 @@ struct c_declspecs {
specifier, in bytes, or -1 if no such specifiers with nonzero
alignment. */
int align_log;
- /* For the __intN declspec, this stores the index into the int_n_* arrays. */
- int int_n_idx;
- /* For the _FloatN and _FloatNx declspec, this stores the index into
- the floatn_nx_types array. */
- int floatn_nx_idx;
+ union {
+ /* For the __intN declspec, this stores the index into the int_n_*
+ arrays. */
+ int int_n_idx;
+ /* For the _FloatN and _FloatNx declspec, this stores the index into
+ the floatn_nx_types array. */
+ int floatn_nx_idx;
+ /* For _BitInt(N) this stores the N. */
+ int bitint_prec;
+ } u;
/* The storage class specifier, or csc_none if none. */
enum c_storage_class storage_class;
/* Any type specifier keyword used such as "int", not reflecting
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e6ddf37..5bb9f83 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -413,10 +413,12 @@ composite_type (tree t1, tree t2)
the composite type. */
if (code1 == ENUMERAL_TYPE
- && (code2 == INTEGER_TYPE || code2 == BOOLEAN_TYPE))
+ && (code2 == INTEGER_TYPE
+ || code2 == BOOLEAN_TYPE))
return t1;
if (code2 == ENUMERAL_TYPE
- && (code1 == INTEGER_TYPE || code1 == BOOLEAN_TYPE))
+ && (code1 == INTEGER_TYPE
+ || code1 == BOOLEAN_TYPE))
return t2;
gcc_assert (code1 == code2);
@@ -764,10 +766,10 @@ c_common_type (tree t1, tree t2)
gcc_assert (code1 == VECTOR_TYPE || code1 == COMPLEX_TYPE
|| code1 == FIXED_POINT_TYPE || code1 == REAL_TYPE
- || code1 == INTEGER_TYPE);
+ || code1 == INTEGER_TYPE || code1 == BITINT_TYPE);
gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
|| code2 == FIXED_POINT_TYPE || code2 == REAL_TYPE
- || code2 == INTEGER_TYPE);
+ || code2 == INTEGER_TYPE || code2 == BITINT_TYPE);
/* When one operand is a decimal float type, the other operand cannot be
a generic float type or a complex type. We also disallow vector types
@@ -1004,6 +1006,20 @@ c_common_type (tree t1, tree t2)
if (mv1 == FLOATNX_TYPE_NODE (i) || mv2 == FLOATNX_TYPE_NODE (i))
return FLOATNX_TYPE_NODE (i);
+ 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 code1 == BITINT_TYPE ? t2 : t1;
+ /* If BITINT_TYPE is unsigned and the other type is signed
+ non-BITINT_TYPE with the same precision, the latter has higher rank.
+ In that case:
+ Otherwise, both operands are converted to the unsigned integer type
+ corresponding to the type of the operand with signed integer type. */
+ if (TYPE_UNSIGNED (code1 == BITINT_TYPE ? t1 : t2))
+ return c_common_unsigned_type (code1 == BITINT_TYPE ? t2 : t1);
+ }
+
/* Otherwise prefer the unsigned one. */
if (TYPE_UNSIGNED (t1))
@@ -1177,6 +1193,7 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
case INTEGER_TYPE:
case FIXED_POINT_TYPE:
case REAL_TYPE:
+ case BITINT_TYPE:
/* With these nodes, we can't determine type equivalence by
looking at what is stored in the nodes themselves, because
two nodes might have different TYPE_MAIN_VARIANTs but still
@@ -2260,12 +2277,17 @@ perform_integral_promotions (tree exp)
/* ??? This should no longer be needed now bit-fields have their
proper types. */
if (TREE_CODE (exp) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
+ && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)))
+ {
+ if (TREE_CODE (DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1)))
+ == BITINT_TYPE)
+ return convert (DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1)), exp);
/* If it's thinner than an int, promote it like a
c_promoting_integer_type_p, otherwise leave it alone. */
- && compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
- TYPE_PRECISION (integer_type_node)) < 0)
- return convert (integer_type_node, exp);
+ if (compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
+ TYPE_PRECISION (integer_type_node)) < 0)
+ return convert (integer_type_node, exp);
+ }
if (c_promoting_integer_type_p (type))
{
@@ -2790,7 +2812,8 @@ build_array_ref (location_t loc, tree array, tree index)
if (index == error_mark_node)
return error_mark_node;
- gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
+ gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
+ || TREE_CODE (TREE_TYPE (index)) == BITINT_TYPE);
bool was_vector = VECTOR_TYPE_P (TREE_TYPE (array));
bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, index);
@@ -4558,6 +4581,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
associativity, but won't generate any code. */
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
+ || typecode == BITINT_TYPE
|| gnu_vector_type_p (TREE_TYPE (arg))))
{
error_at (location, "wrong type argument to unary plus");
@@ -4571,6 +4595,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
+ || typecode == BITINT_TYPE
|| gnu_vector_type_p (TREE_TYPE (arg))))
{
error_at (location, "wrong type argument to unary minus");
@@ -4583,6 +4608,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
case BIT_NOT_EXPR:
/* ~ works on integer types and non float vectors. */
if (typecode == INTEGER_TYPE
+ || typecode == BITINT_TYPE
|| (gnu_vector_type_p (TREE_TYPE (arg))
&& !VECTOR_FLOAT_TYPE_P (TREE_TYPE (arg))))
{
@@ -4657,7 +4683,8 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
case TRUTH_NOT_EXPR:
if (typecode != INTEGER_TYPE && typecode != FIXED_POINT_TYPE
&& typecode != REAL_TYPE && typecode != POINTER_TYPE
- && typecode != COMPLEX_TYPE && typecode != NULLPTR_TYPE)
+ && typecode != COMPLEX_TYPE && typecode != NULLPTR_TYPE
+ && typecode != BITINT_TYPE)
{
error_at (location,
"wrong type argument to unary exclamation mark");
@@ -4769,7 +4796,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
if (typecode != POINTER_TYPE && typecode != FIXED_POINT_TYPE
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE
- && typecode != COMPLEX_TYPE
+ && typecode != COMPLEX_TYPE && typecode != BITINT_TYPE
&& !gnu_vector_type_p (TREE_TYPE (arg)))
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
@@ -5351,9 +5378,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
if ((TREE_CODE (op1) == EXCESS_PRECISION_EXPR
|| TREE_CODE (op2) == EXCESS_PRECISION_EXPR)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE)
+ || code1 == COMPLEX_TYPE || code1 == BITINT_TYPE)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE
- || code2 == COMPLEX_TYPE))
+ || code2 == COMPLEX_TYPE || code2 == BITINT_TYPE))
{
semantic_result_type = c_common_type (type1, type2);
if (TREE_CODE (op1) == EXCESS_PRECISION_EXPR)
@@ -5394,9 +5421,9 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
result_type = TYPE_MAIN_VARIANT (type1);
}
else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE)
+ || code1 == COMPLEX_TYPE || code1 == BITINT_TYPE)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE
- || code2 == COMPLEX_TYPE))
+ || code2 == COMPLEX_TYPE || code2 == BITINT_TYPE))
{
/* In C11, a conditional expression between a floating-point
type and an integer type should convert the integer type to
@@ -5583,7 +5610,8 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
(build_qualified_type (void_type_node, qual));
}
}
- else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
+ else if (code1 == POINTER_TYPE
+ && (code2 == INTEGER_TYPE || code2 == BITINT_TYPE))
{
if (!null_pointer_constant_p (orig_op2))
pedwarn (colon_loc, 0,
@@ -5594,7 +5622,8 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
}
result_type = type1;
}
- else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ else if (code2 == POINTER_TYPE
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
if (!null_pointer_constant_p (orig_op1))
pedwarn (colon_loc, 0,
@@ -6165,7 +6194,8 @@ build_c_cast (location_t loc, tree type, tree expr)
warning_at (loc, OPT_Wcast_align,
"cast increases required alignment of target type");
- if (TREE_CODE (type) == INTEGER_TYPE
+ if ((TREE_CODE (type) == INTEGER_TYPE
+ || TREE_CODE (type) == BITINT_TYPE)
&& TREE_CODE (otype) == POINTER_TYPE
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype))
/* Unlike conversion of integers to pointers, where the
@@ -6183,7 +6213,8 @@ build_c_cast (location_t loc, tree type, tree expr)
"to non-matching type %qT", otype, type);
if (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (otype) == INTEGER_TYPE
+ && (TREE_CODE (otype) == INTEGER_TYPE
+ || TREE_CODE (otype) == BITINT_TYPE)
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype)
/* Don't warn about converting any constant. */
&& !TREE_CONSTANT (value))
@@ -7135,11 +7166,11 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
|| codel == FIXED_POINT_TYPE
|| codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
- || codel == BOOLEAN_TYPE)
+ || codel == BOOLEAN_TYPE || codel == BITINT_TYPE)
&& (coder == INTEGER_TYPE || coder == REAL_TYPE
|| coder == FIXED_POINT_TYPE
|| coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
- || coder == BOOLEAN_TYPE))
+ || coder == BOOLEAN_TYPE || coder == BITINT_TYPE))
{
if (warnopt && errtype == ic_argpass)
maybe_warn_builtin_no_proto_arg (expr_loc, fundecl, parmnum, type,
@@ -7715,7 +7746,9 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
return error_mark_node;
}
else if (codel == POINTER_TYPE
- && (coder == INTEGER_TYPE || coder == NULLPTR_TYPE))
+ && (coder == INTEGER_TYPE
+ || coder == NULLPTR_TYPE
+ || coder == BITINT_TYPE))
{
/* An explicit constant 0 or type nullptr_t can convert to a pointer,
or one that results from arithmetic, even including a cast to
@@ -7756,7 +7789,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
return convert (type, rhs);
}
- else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
+ else if ((codel == INTEGER_TYPE || codel == BITINT_TYPE)
+ && coder == POINTER_TYPE)
{
switch (errtype)
{
@@ -8566,7 +8600,8 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
if (code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE
|| code == POINTER_TYPE || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
- || code == COMPLEX_TYPE || code == VECTOR_TYPE || code == NULLPTR_TYPE)
+ || code == COMPLEX_TYPE || code == VECTOR_TYPE || code == NULLPTR_TYPE
+ || code == BITINT_TYPE)
{
tree unconverted_init = inside_init;
if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
@@ -12361,12 +12396,14 @@ build_binary_op (location_t location, enum tree_code code,
{
case PLUS_EXPR:
/* Handle the pointer + int case. */
- if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ if (code0 == POINTER_TYPE
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
ret = pointer_int_sum (location, PLUS_EXPR, op0, op1);
goto return_build_binary_op;
}
- else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
+ else if (code1 == POINTER_TYPE
+ && (code0 == INTEGER_TYPE || code0 == BITINT_TYPE))
{
ret = pointer_int_sum (location, PLUS_EXPR, op1, op0);
goto return_build_binary_op;
@@ -12385,7 +12422,8 @@ build_binary_op (location_t location, enum tree_code code,
goto return_build_binary_op;
}
/* Handle pointer minus int. Just like pointer plus int. */
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ else if (code0 == POINTER_TYPE
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
ret = pointer_int_sum (location, MINUS_EXPR, op0, op1);
goto return_build_binary_op;
@@ -12407,11 +12445,11 @@ build_binary_op (location_t location, enum tree_code code,
warn_for_div_by_zero (location, op1);
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == FIXED_POINT_TYPE
+ || code0 == FIXED_POINT_TYPE || code0 == BITINT_TYPE
|| code0 == COMPLEX_TYPE
|| gnu_vector_type_p (type0))
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == FIXED_POINT_TYPE
+ || code1 == FIXED_POINT_TYPE || code1 == BITINT_TYPE
|| code1 == COMPLEX_TYPE
|| gnu_vector_type_p (type1)))
{
@@ -12422,8 +12460,9 @@ build_binary_op (location_t location, enum tree_code code,
if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
- if (!((tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE)
- || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE)))
+ if (!(((tcode0 == INTEGER_TYPE || tcode0 == BITINT_TYPE)
+ && (tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE))
+ || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE)))
resultcode = RDIV_EXPR;
else
/* Although it would be tempting to shorten always here, that
@@ -12439,7 +12478,8 @@ build_binary_op (location_t location, enum tree_code code,
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ if ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
shorten = -1;
/* Allow vector types which are not floating point types. */
else if (gnu_vector_type_p (type0)
@@ -12459,7 +12499,8 @@ build_binary_op (location_t location, enum tree_code code,
&& 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 ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
/* Although it would be tempting to shorten always here, that loses
on some targets, since the modulo instruction is undefined if the
@@ -12477,10 +12518,12 @@ build_binary_op (location_t location, enum tree_code code,
case TRUTH_XOR_EXPR:
if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
|| code0 == REAL_TYPE || code0 == COMPLEX_TYPE
- || code0 == FIXED_POINT_TYPE || code0 == NULLPTR_TYPE)
+ || code0 == FIXED_POINT_TYPE || code0 == NULLPTR_TYPE
+ || code0 == BITINT_TYPE)
&& (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
|| code1 == REAL_TYPE || code1 == COMPLEX_TYPE
- || code1 == FIXED_POINT_TYPE || code1 == NULLPTR_TYPE))
+ || code1 == FIXED_POINT_TYPE || code1 == NULLPTR_TYPE
+ || code1 == BITINT_TYPE))
{
/* Result of these operations is always an int,
but that does not mean the operands should be
@@ -12543,9 +12586,10 @@ build_binary_op (location_t location, enum tree_code code,
converted = 1;
}
else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE
+ || code0 == BITINT_TYPE
|| (gnu_vector_type_p (type0)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE))
- && code1 == INTEGER_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
doing_shift = true;
if (TREE_CODE (op1) == INTEGER_CST)
@@ -12603,9 +12647,10 @@ build_binary_op (location_t location, enum tree_code code,
converted = 1;
}
else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE
+ || code0 == BITINT_TYPE
|| (gnu_vector_type_p (type0)
&& TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE))
- && code1 == INTEGER_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
doing_shift = true;
if (TREE_CODE (op0) == INTEGER_CST
@@ -12719,9 +12764,10 @@ build_binary_op (location_t location, enum tree_code code,
/* Result of comparison is always int,
but don't convert the args to int! */
build_type = integer_type_node;
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == BITINT_TYPE
|| code0 == FIXED_POINT_TYPE || code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == BITINT_TYPE
|| code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE))
short_compare = 1;
else if (code0 == POINTER_TYPE
@@ -12782,12 +12828,14 @@ build_binary_op (location_t location, enum tree_code code,
(build_qualified_type (void_type_node, qual));
}
}
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ else if (code0 == POINTER_TYPE
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
result_type = type0;
pedwarn (location, 0, "comparison between pointer and integer");
}
- else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+ else if ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE)
+ && code1 == POINTER_TYPE)
{
result_type = type1;
pedwarn (location, 0, "comparison between pointer and integer");
@@ -12875,9 +12923,9 @@ build_binary_op (location_t location, enum tree_code code,
}
build_type = integer_type_node;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == FIXED_POINT_TYPE)
+ || code0 == BITINT_TYPE || code0 == FIXED_POINT_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == FIXED_POINT_TYPE))
+ || code1 == BITINT_TYPE || code1 == FIXED_POINT_TYPE))
short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
@@ -12936,12 +12984,14 @@ build_binary_op (location_t location, enum tree_code code,
warning_at (location, OPT_Wextra,
"ordered comparison of pointer with integer zero");
}
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ else if (code0 == POINTER_TYPE
+ && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
{
result_type = type0;
pedwarn (location, 0, "comparison between pointer and integer");
}
- else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+ else if ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE)
+ && code1 == POINTER_TYPE)
{
result_type = type1;
pedwarn (location, 0, "comparison between pointer and integer");
@@ -12995,12 +13045,11 @@ build_binary_op (location_t location, enum tree_code code,
}
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
- || code0 == FIXED_POINT_TYPE
+ || code0 == FIXED_POINT_TYPE || code0 == BITINT_TYPE
|| gnu_vector_type_p (type0))
- &&
- (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
- || code1 == FIXED_POINT_TYPE
- || gnu_vector_type_p (type1)))
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
+ || code1 == FIXED_POINT_TYPE || code1 == BITINT_TYPE
+ || gnu_vector_type_p (type1)))
{
bool first_complex = (code0 == COMPLEX_TYPE);
bool second_complex = (code1 == COMPLEX_TYPE);