From: neil Date: Tue, 29 Jan 2002 17:19:58 +0000 (+0000) Subject: PR c/3325 X-Git-Tag: upstream/4.9.2~89053 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c0d30539e9c2fa194ea098295a898fa7b9ef7cca;p=platform%2Fupstream%2Flinaro-gcc.git PR c/3325 * c-decl.c (enum_decl_context): Remove BITFIELD. (grokdeclarator): Take bitfield width as an input. Ensure bitfields are given the correct type. Perform bitfield width validation with build_bitfield_integer_type rather than waiting for finish_struct. (grok_typename, grok_typename_in_parm_context, start_decl, push_parmdecl, grokfield, start_function): Update calls to grokdeclarator. (build_bitfield_integer_type): New function. (finish_struct): Move bitfield validation to grokdeclarator and build_bitfield_integer_type. * tree.c (build_nonstandard_integer_type): New function. * tree.h (build_nonstandard_integer_type): New prototype. objc: * objc-act.c (objc_copy_list): Remove DECL_INITIAL kludge. testsuite: * gcc.c-torture/compile/20000224-1.c: Update. * gcc.c-torture/execute/bitfld-1.c: New tests. * gcc.dg/bitfld-1.c, bitfld-2.c: Diagnostic tests. * gcc.dg/uninit-A.c: Update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49321 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d201d87..a0f5e31 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2002-01-29 Neil Booth + + PR c/3325, c/3326, c/2511, c/3347 + * c-decl.c (enum_decl_context): Remove BITFIELD. + (grokdeclarator): Take bitfield width as an input. + Ensure bitfields are given the correct type. Perform + bitfield width validation with build_bitfield_integer_type + rather than waiting for finish_struct. + (grok_typename, grok_typename_in_parm_context, start_decl, + push_parmdecl, grokfield, start_function): Update calls to + grokdeclarator. + (build_bitfield_integer_type): New function. + (finish_struct): Move bitfield validation to grokdeclarator + and build_bitfield_integer_type. + * tree.c (build_nonstandard_integer_type): New function. + * tree.h (build_nonstandard_integer_type): New prototype. +objc: + * objc-act.c (objc_copy_list): Remove DECL_INITIAL kludge. + 2002-01-29 Jakub Jelinek PR other/1502: diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 54ec18c..ad23809 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -53,7 +53,6 @@ enum decl_context FUNCDEF, /* Function definition */ PARM, /* Declaration of parm before function body */ FIELD, /* Declaration inside struct or union */ - BITFIELD, /* Likewise but with specified width */ TYPENAME}; /* Typename (inside cast or sizeof) */ @@ -276,12 +275,13 @@ static tree lookup_tag PARAMS ((enum tree_code, tree, struct binding_level *, int)); static tree lookup_tag_reverse PARAMS ((tree)); static tree grokdeclarator PARAMS ((tree, tree, enum decl_context, - int)); + int, tree)); static tree grokparms PARAMS ((tree, int)); static void layout_array_type PARAMS ((tree)); static tree c_make_fname_decl PARAMS ((tree, int)); static void c_expand_body PARAMS ((tree, int, int)); static void warn_if_shadowing PARAMS ((tree, tree)); +static tree build_bitfield_integer_type PARAMS ((tree, tree, const char *)); /* C-specific option variables. */ @@ -319,7 +319,7 @@ int flag_noniso_default_format_attributes = 1; being traditional. */ int flag_allow_single_precision = 0; -/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */ +/* Nonzero means to treat bit-fields as signed unless they say `unsigned'. */ int flag_signed_bitfields = 1; int explicit_flag_signed_bitfields = 0; @@ -3390,7 +3390,8 @@ groktypename (typename) split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs); - typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0); + typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0, + NULL_TREE); /* Apply attributes. */ decl_attributes (&typename, attrs, 0); @@ -3408,7 +3409,7 @@ groktypename_in_parm_context (typename) return typename; return grokdeclarator (TREE_VALUE (typename), TREE_PURPOSE (typename), - PARM, 0); + PARM, 0, NULL_TREE); } /* Decode a declarator in an ordinary declaration or data definition. @@ -3441,7 +3442,7 @@ start_decl (declarator, declspecs, initialized, attributes) deprecated_state = DEPRECATED_SUPPRESS; decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized); + NORMAL, initialized, NULL_TREE); deprecated_state = DEPRECATED_NORMAL; @@ -3819,7 +3820,8 @@ push_parm_decl (parm) immediate_size_expand = 0; decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)), - TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0); + TREE_PURPOSE (TREE_PURPOSE (parm)), + PARM, 0, NULL_TREE); decl_attributes (&decl, TREE_VALUE (parm), 0); #if 0 @@ -3979,6 +3981,92 @@ complete_array_type (type, initial_value, do_default) return value; } +/* A bit-field NAME should have an integer type whose precision + accurately reflects its WIDTH. If TYPE is good for that, return + it, otherwise create and return the appropriate type. + + This routine also performs sanity checks on the bit-field's type + and width, and uses appropriate values if they are invalid. */ +static tree +build_bitfield_integer_type (type, width, orig_name) + tree type, width; + const char *orig_name; +{ + tree type_mv; + unsigned int max_width; + unsigned HOST_WIDE_INT w; + const char *name = orig_name ? orig_name: _(""); + + /* Necessary? */ + STRIP_NOPS (width); + + /* Detect and ignore out of range field width and process valid + field widths. */ + if (TREE_CODE (width) != INTEGER_CST) + { + error ("bit-field `%s' width not an integer constant", name); + width = integer_one_node; + } + else + { + constant_expression_warning (width); + if (tree_int_cst_sgn (width) < 0) + { + error ("negative width in bit-field `%s'", name); + width = integer_one_node; + } + else if (integer_zerop (width) && orig_name) + { + error ("zero width for bit-field `%s'", name); + width = integer_one_node; + } + } + + /* Detect invalid bit-field type. */ + if (TREE_CODE (type) != INTEGER_TYPE + && TREE_CODE (type) != BOOLEAN_TYPE + && TREE_CODE (type) != ENUMERAL_TYPE) + { + error ("bit-field `%s' has invalid type", name); + type = unsigned_type_node; + } + + type_mv = TYPE_MAIN_VARIANT (type); + if (pedantic + && type_mv != integer_type_node + && type_mv != unsigned_type_node + && type_mv != c_bool_type_node + /* Accept an enum that's equivalent to int or unsigned int. */ + && (TREE_CODE (type) != ENUMERAL_TYPE + || TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))) + pedwarn ("type of bit-field `%s' is a GCC extension", name); + + if (type_mv == c_bool_type_node) + max_width = CHAR_TYPE_SIZE; + else + max_width = TYPE_PRECISION (type); + + if (0 < compare_tree_int (width, max_width)) + { + error ("width of `%s' exceeds its type", name); + w = max_width; + } + else + w = tree_low_cst (width, 1); + + if (TREE_CODE (type) == ENUMERAL_TYPE + && (w < min_precision (TYPE_MIN_VALUE (type), TREE_UNSIGNED (type)) + || w < min_precision (TYPE_MAX_VALUE (type), TREE_UNSIGNED (type)))) + warning ("`%s' is narrower than values of its type", name); + + /* The type of a bit-field should have precision the same as the + bit-field's width. */ + if (w != TYPE_PRECISION (type)) + type = build_nonstandard_integer_type (w, TREE_UNSIGNED (type)); + + return type; +} + /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. @@ -3998,8 +4086,9 @@ complete_array_type (type, initial_value, do_default) TYPENAME if for a typename (in a cast or sizeof). Don't make a DECL node; just return the ..._TYPE node. FIELD for a struct or union field; make a FIELD_DECL. - BITFIELD for a field with specified width. INITIALIZED is 1 if the decl has an initializer. + WIDTH is non-NULL for bit-fields, and is an INTEGER_CST node representing + the width of the bit-field. In the TYPENAME case, DECLARATOR is really an absolute declarator. It may also be so in the PARM case, for a prototype where the @@ -4009,11 +4098,12 @@ complete_array_type (type, initial_value, do_default) and `extern' are interpreted. */ static tree -grokdeclarator (declarator, declspecs, decl_context, initialized) +grokdeclarator (declarator, declspecs, decl_context, initialized, width) tree declspecs; tree declarator; enum decl_context decl_context; int initialized; + tree width; { int specbits = 0; tree spec; @@ -4028,19 +4118,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) int explicit_char = 0; int defaulted_int = 0; tree typedef_decl = 0; - const char *name; + const char *name, *orig_name; tree typedef_type = 0; int funcdef_flag = 0; enum tree_code innermost_code = ERROR_MARK; - int bitfield = 0; int size_varies = 0; tree decl_attr = NULL_TREE; tree array_ptr_quals = NULL_TREE; int array_parm_static = 0; tree returned_attrs = NULL_TREE; - - if (decl_context == BITFIELD) - bitfield = 1, decl_context = FIELD; + bool bitfield = width != NULL_TREE; if (decl_context == FUNCDEF) funcdef_flag = 1, decl_context = NORMAL; @@ -4073,6 +4160,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) default: abort (); } + orig_name = name; if (name == 0) name = "type name"; } @@ -4284,9 +4372,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) } /* Decide whether an integer type is signed or not. - Optionally treat bitfields as signed by default. */ + Optionally treat bit-fields as signed by default. */ if (specbits & 1 << (int) RID_UNSIGNED - /* Traditionally, all bitfields are unsigned. */ + /* Traditionally, all bit-fields are unsigned. */ || (bitfield && flag_traditional && (! explicit_flag_signed_bitfields || !flag_signed_bitfields)) || (bitfield && ! flag_signed_bitfields @@ -4359,6 +4447,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) } } + /* A bit-field needs its type to have precision equal to its width, + rather than the precision of the specified standard type. */ + if (bitfield) + type = build_bitfield_integer_type (type, width, orig_name); + /* Figure out the type qualifiers for the declaration. There are two ways a declaration can become qualified. One is something like `const int i' where the `const' is explicit. Another is @@ -5008,7 +5101,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) else if (decl_context == FIELD) { /* Structure field. It may not be a function. */ - if (TREE_CODE (type) == FUNCTION_TYPE) { error ("field `%s' declared as a function", name); @@ -5032,6 +5124,29 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) #endif } decl = build_decl (FIELD_DECL, declarator, type); + if (bitfield) + { + DECL_SIZE (decl) = bitsize_int (TYPE_PRECISION (type)); + DECL_BIT_FIELD (decl) = 1; + SET_DECL_C_BIT_FIELD (decl); + + /* Bit-field width 0 => force desired amount of alignment. */ + if (TYPE_PRECISION (type) == 0) + { +#ifdef EMPTY_FIELD_BOUNDARY + DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl), + EMPTY_FIELD_BOUNDARY); +#endif +#ifdef PCC_BITFIELD_TYPE_MATTERS + if (PCC_BITFIELD_TYPE_MATTERS) + { + DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl), + TYPE_ALIGN (type)); + DECL_USER_ALIGN (decl) |= TYPE_USER_ALIGN (type); + } +#endif + } + } DECL_NONADDRESSABLE_P (decl) = bitfield; if (size_varies) @@ -5534,7 +5649,7 @@ start_struct (code, name) /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) of a structure component, returning a FIELD_DECL node. - WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. + WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node. This is done during the parsing of the struct declaration. The FIELD_DECL nodes are chained together and the lot of them @@ -5560,10 +5675,9 @@ grokfield (filename, line, declarator, declspecs, width) } } - value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0); + value = grokdeclarator (declarator, declspecs, FIELD, 0, width); finish_decl (value, NULL_TREE, NULL_TREE); - DECL_INITIAL (value) = width; maybe_objc_check_decl (value); return value; @@ -5615,10 +5729,7 @@ finish_struct (t, fieldlist, attributes) fieldlist ? _("named members") : _("members")); } - /* Install struct as DECL_CONTEXT of each field decl. - Also process specified field sizes,m which is found in the DECL_INITIAL. - Store 0 there, except for ": 0" fields (so we can find them - and delete them, below). */ + /* Install struct as DECL_CONTEXT of each field decl. */ saw_named_field = 0; for (x = fieldlist; x; x = TREE_CHAIN (x)) @@ -5654,93 +5765,7 @@ finish_struct (t, fieldlist, attributes) error ("nested redefinition of `%s'", IDENTIFIER_POINTER (TYPE_NAME (t))); - /* Detect invalid bit-field size. */ - if (DECL_INITIAL (x)) - STRIP_NOPS (DECL_INITIAL (x)); - if (DECL_INITIAL (x)) - { - if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST) - constant_expression_warning (DECL_INITIAL (x)); - else - { - error_with_decl (x, - "bit-field `%s' width not an integer constant"); - DECL_INITIAL (x) = NULL; - } - } - - /* Detect invalid bit-field type. */ - if (DECL_INITIAL (x) - && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE - && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE) - { - error_with_decl (x, "bit-field `%s' has invalid type"); - DECL_INITIAL (x) = NULL; - } - - if (DECL_INITIAL (x) && pedantic - && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node - && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node - && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node - /* Accept an enum that's equivalent to int or unsigned int. */ - && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE - && (TYPE_PRECISION (TREE_TYPE (x)) - == TYPE_PRECISION (integer_type_node)))) - pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C"); - - /* Detect and ignore out of range field width and process valid - field widths. */ - if (DECL_INITIAL (x)) - { - int max_width - = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node - ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x))); - - if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0) - error_with_decl (x, "negative width in bit-field `%s'"); - else if (0 < compare_tree_int (DECL_INITIAL (x), max_width)) - pedwarn_with_decl (x, "width of `%s' exceeds its type"); - else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0) - error_with_decl (x, "zero width for bit-field `%s'"); - else - { - /* The test above has assured us that TREE_INT_CST_HIGH is 0. */ - unsigned HOST_WIDE_INT width - = tree_low_cst (DECL_INITIAL (x), 1); - - if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE - && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)), - TREE_UNSIGNED (TREE_TYPE (x))) - || (width - < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)), - TREE_UNSIGNED (TREE_TYPE (x)))))) - warning_with_decl (x, - "`%s' is narrower than values of its type"); - - DECL_SIZE (x) = bitsize_int (width); - DECL_BIT_FIELD (x) = 1; - SET_DECL_C_BIT_FIELD (x); - - if (width == 0) - { - /* field size 0 => force desired amount of alignment. */ -#ifdef EMPTY_FIELD_BOUNDARY - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY); -#endif -#ifdef PCC_BITFIELD_TYPE_MATTERS - if (PCC_BITFIELD_TYPE_MATTERS) - { - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); - DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x)); - } -#endif - } - } - } - - else if (TREE_TYPE (x) != error_mark_node) + if (TREE_TYPE (x) != error_mark_node && !DECL_BIT_FIELD (x)) { unsigned int min_align = (DECL_PACKED (x) ? BITS_PER_UNIT : TYPE_ALIGN (TREE_TYPE (x))); @@ -5752,8 +5777,6 @@ finish_struct (t, fieldlist, attributes) DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x)); } - DECL_INITIAL (x) = 0; - /* Detect flexible array member in an invalid context. */ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE && TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE @@ -6178,7 +6201,7 @@ start_function (declspecs, declarator, attributes) /* Don't expand any sizes in the return type of the function. */ immediate_size_expand = 0; - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1); + decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE); /* If the declarator is not suitable for a function definition, cause a syntax error. */ diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 0a57d65..91b2223 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2393,13 +2393,6 @@ objc_copy_list (list, head) while (list) { tail = copy_node (list); - - /* The following statement fixes a bug when inheriting instance - variables that are declared to be bitfields. finish_struct - expects to find the width of the bitfield in DECL_INITIAL. */ - if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0) - DECL_INITIAL (tail) = DECL_SIZE (tail); - newlist = chainon (newlist, tail); list = TREE_CHAIN (list); } diff --git a/gcc/testsuite/gcc.c-torture/compile/20000224-1.c b/gcc/testsuite/gcc.c-torture/compile/20000224-1.c index 3572c33..1c72b6a 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20000224-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20000224-1.c @@ -15,7 +15,7 @@ union Lisp_Object { enum Lisp_Type type: 3L ; unsigned long markbit: 1; - unsigned long val: 60; + unsigned long val: 32; } gu; long i; } diff --git a/gcc/testsuite/gcc.c-torture/execute/bitfld-1.c b/gcc/testsuite/gcc.c-torture/execute/bitfld-1.c new file mode 100644 index 0000000..b7e86e8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/bitfld-1.c @@ -0,0 +1,54 @@ +/* Copyright 2002 Free Software Foundation, Inc. + + Tests correct signedness of operations on bitfields; in particular + that integer promotions are done correctly, including the case when + casts are present. + + The C front end was eliding the cast of an unsigned bitfield to + unsigned as a no-op, when in fact it forces a conversion to a + full-width unsigned int. (At the time of writing, the C++ front end + has a different bug; it erroneously promotes the uncast unsigned + bitfield to an unsigned int). + + Source: Neil Booth, 25 Jan 2002, based on PR 3325 (and 3326, which + is a different manifestation of the same bug). +*/ + +extern void abort (); + +int +main(int argc, char *argv[]) +{ + struct x { signed int i : 7; unsigned int u : 7; } bit; + + unsigned int u; + int i; + unsigned int unsigned_result = -13U % 61; + int signed_result = -13 % 61; + + bit.u = 61, u = 61; + bit.i = -13, i = -13; + + if (i % u != unsigned_result) + abort (); + if (i % (unsigned int) u != unsigned_result) + abort (); + + /* Somewhat counter-intuitively, bit.u is promoted to an int, making + the operands and result an int. */ + if (i % bit.u != signed_result) + abort (); + + if (bit.i % bit.u != signed_result) + abort (); + + /* But with a cast to unsigned int, the unsigned int is promoted to + itself as a no-op, and the operands and result are unsigned. */ + if (i % (unsigned int) bit.u != unsigned_result) + abort (); + + if (bit.i % (unsigned int) bit.u != unsigned_result) + abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/bitfld-1.c b/gcc/testsuite/gcc.dg/bitfld-1.c new file mode 100644 index 0000000..ce37cc4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitfld-1.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + + Tests various diagnostics about a bit-field's type and width. + + Source: Neil Booth, 26 Jan 2002. +*/ + +/* { dg-options -pedantic } */ + +enum foo {e1 = 0, e2, e3, e4, e5}; + +int x; +typedef unsigned int ui; + +struct bf1 +{ + unsigned int a: 3.5; /* { dg-error "integer constant" } */ + unsigned int b: x; /* { dg-error "integer constant" } */ + unsigned int c: -1; /* { dg-error "negative width" } */ + unsigned int d: 0; /* { dg-error "zero width" } */ + unsigned int : 0; /* { dg-bogus "zero width" } */ + unsigned int : 5; + double e: 1; /* { dg-error "invalid type" } */ + float f: 1; /* { dg-error "invalid type" } */ + unsigned long g: 5; /* { dg-warning "GCC extension" } */ + ui h: 5; + enum foo i: 2; /* { dg-error "narrower" } */ + enum foo j: 3; + unsigned int k: 256; /* { dg-error "exceeds its type" } */ +}; diff --git a/gcc/testsuite/gcc.dg/bitfld-2.c b/gcc/testsuite/gcc.dg/bitfld-2.c new file mode 100644 index 0000000..e3f5f1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitfld-2.c @@ -0,0 +1,23 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. + + Tests we warn about overly-large assignments to bitfields. + + Source: Neil Booth, 28 Jan 2002. +*/ + +struct bf +{ + unsigned int a: 2; + int b: 2; +}; + +struct bf p = {4, 0}; /* { dg-warning "truncated" } */ +struct bf q = {0, 2}; /* { dg-warning "overflow" } */ +struct bf r = {3, -2}; /* { dg-bogus "(truncated|overflow)" } */ + +void foo () +{ + p.a = 4, p.b = 0; /* { dg-warning "truncated" } */ + q.a = 0, q.b = 2; /* { dg-warning "overflow" } */ + r.a = 3, r.b = -2; /* { dg-bogus "(truncated|overflow)" } */ +} diff --git a/gcc/testsuite/gcc.dg/uninit-A.c b/gcc/testsuite/gcc.dg/uninit-A.c index 119ed69..48df204 100644 --- a/gcc/testsuite/gcc.dg/uninit-A.c +++ b/gcc/testsuite/gcc.dg/uninit-A.c @@ -8,7 +8,9 @@ struct tree { struct tree *car, *cdr, *wfl; int code; - struct { int renp:1; int rtnp:1; int rpnp:1; } flags; + struct { unsigned int renp:1; + unsigned int rtnp:1; + unsigned int rpnp:1; } flags; }; typedef struct tree *tree; #define NULL_TREE ((tree)0) diff --git a/gcc/tree.c b/gcc/tree.c index 86c0cd0..8d22d68 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3758,6 +3758,29 @@ build_index_type (maxval) return itype; } +/* Builds a signed or unsigned integer type of precision PRECISION. + Used for C bitfields whose precision does not match that of + built-in target types. */ +tree +build_nonstandard_integer_type (precision, unsignedp) + unsigned HOST_WIDE_INT precision; + int unsignedp; +{ + tree itype = make_node (INTEGER_TYPE); + + TYPE_PRECISION (itype) = precision; + + if (unsignedp) + fixup_unsigned_type (itype); + else + fixup_signed_type (itype); + + if (host_integerp (TYPE_MAX_VALUE (itype), 1)) + return type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype); + + return itype; +} + /* Create a range of some discrete type TYPE (an INTEGER_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, or CHAR_TYPE), with low bound LOWVAL and high bound HIGHVAL. diff --git a/gcc/tree.h b/gcc/tree.h index a277bad..930d820 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2860,6 +2860,7 @@ extern tree getdecls PARAMS ((void)); /* Function to return the chain of structure tags in the current scope level. */ extern tree gettags PARAMS ((void)); +extern tree build_nonstandard_integer_type PARAMS ((unsigned int, int)); extern tree build_range_type PARAMS ((tree, tree, tree)); /* In alias.c */