aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/c-decl.c251
-rw-r--r--gcc/objc/objc-act.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20000224-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/bitfld-1.c54
-rw-r--r--gcc/testsuite/gcc.dg/bitfld-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/bitfld-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/uninit-A.c4
-rw-r--r--gcc/tree.c23
-rw-r--r--gcc/tree.h1
10 files changed, 291 insertions, 123 deletions
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 <neil@daikokuya.demon.co.uk>
+
+ 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 <jakub@redhat.com>
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: _("<anonymous>");
+
+ /* 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 0a57d65b..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 */