Commit 8469e54e by Neil Booth Committed by Neil Booth

re PR c/3325 (cast of bit-field to same type gets discarded)

	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.

From-SVN: r49321
parent 6c54b16c
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:
......
......@@ -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);
}
......
......@@ -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;
}
......
/* 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;
}
/* 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" } */
};
/* 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)" } */
}
......@@ -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)
......
......@@ -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.
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment