diff options
author | Jakub Jelinek <jakub@redhat.com> | 2023-09-06 17:34:49 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2023-09-06 17:34:49 +0200 |
commit | 8c984a1c3693df63520558631c827bb2c2d8b5bc (patch) | |
tree | 7b4fbfd8dea2c7820cff7436890ebe353795c43f /gcc/c | |
parent | 2ce182e258d3ab11310442d5f4dd1d063018aca9 (diff) | |
download | gcc-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.cc | 11 | ||||
-rw-r--r-- | gcc/c/c-convert.cc | 1 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 194 | ||||
-rw-r--r-- | gcc/c/c-fold.cc | 14 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 32 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 18 | ||||
-rw-r--r-- | gcc/c/c-typeck.cc | 147 |
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); |