aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.cc
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/c-decl.cc
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/c-decl.cc')
-rw-r--r--gcc/c/c-decl.cc194
1 files changed, 145 insertions, 49 deletions
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 ();
}