re PR c/22421 (problems with -Wformat and bit-fields)
PR c/22421 * c-decl.c (c_build_bitfield_integer_type): New function. (finish_struct): Call it. * c-pretty-print.c (pp_c_type_specifier): Handle bit-field types. testsuite: * gcc.dg/format/bitfld-1.c: New test. From-SVN: r102091
This commit is contained in:
parent
8fcef540f3
commit
0b359b0103
@ -1,3 +1,10 @@
|
||||
2005-07-16 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/22421
|
||||
* c-decl.c (c_build_bitfield_integer_type): New function.
|
||||
(finish_struct): Call it.
|
||||
* c-pretty-print.c (pp_c_type_specifier): Handle bit-field types.
|
||||
|
||||
2005-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* c-typeck.c (digest_init): Call 'convert_for_assignment'
|
||||
|
26
gcc/c-decl.c
26
gcc/c-decl.c
@ -3774,6 +3774,30 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
|
||||
warning (0, "%qs is narrower than values of its type", name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */
|
||||
static tree
|
||||
c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
|
||||
{
|
||||
/* Extended integer types of the same width as a standard type have
|
||||
lesser rank, so those of the same width as int promote to int or
|
||||
unsigned int and are valid for printf formats expecting int or
|
||||
unsigned int. To avoid such special cases, avoid creating
|
||||
extended integer types for bit-fields if a standard integer type
|
||||
is available. */
|
||||
if (width == TYPE_PRECISION (integer_type_node))
|
||||
return unsignedp ? unsigned_type_node : integer_type_node;
|
||||
if (width == TYPE_PRECISION (signed_char_type_node))
|
||||
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
||||
if (width == TYPE_PRECISION (short_integer_type_node))
|
||||
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
||||
if (width == TYPE_PRECISION (long_integer_type_node))
|
||||
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
||||
if (width == TYPE_PRECISION (long_long_integer_type_node))
|
||||
return (unsignedp ? long_long_unsigned_type_node
|
||||
: long_long_integer_type_node);
|
||||
return build_nonstandard_integer_type (width, unsignedp);
|
||||
}
|
||||
|
||||
/* Given declspecs and a declarator,
|
||||
determine the name and type of the object declared
|
||||
@ -5376,7 +5400,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
|
||||
if (width != TYPE_PRECISION (type))
|
||||
{
|
||||
TREE_TYPE (*fieldlistp)
|
||||
= build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
|
||||
= c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type));
|
||||
DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
|
||||
}
|
||||
DECL_INITIAL (*fieldlistp) = 0;
|
||||
|
@ -315,10 +315,21 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
t = TYPE_NAME (t);
|
||||
{
|
||||
t = TYPE_NAME (t);
|
||||
pp_c_type_specifier (pp, t);
|
||||
}
|
||||
else
|
||||
t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
|
||||
pp_c_type_specifier (pp, t);
|
||||
{
|
||||
int prec = TYPE_PRECISION (t);
|
||||
t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
|
||||
pp_c_type_specifier (pp, t);
|
||||
if (TYPE_PRECISION (t) != prec)
|
||||
{
|
||||
pp_string (pp, ":");
|
||||
pp_decimal_int (pp, prec);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_DECL:
|
||||
|
@ -1,3 +1,8 @@
|
||||
2005-07-16 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
PR c/22421
|
||||
* gcc.dg/format/bitfld-1.c: New test.
|
||||
|
||||
2005-07-15 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/22204
|
||||
|
46
gcc/testsuite/gcc.dg/format/bitfld-1.c
Normal file
46
gcc/testsuite/gcc.dg/format/bitfld-1.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* Test for printf formats and bit-fields: bug 22421. */
|
||||
/* Origin: Joseph Myers <joseph@codesourcery.com> */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=gnu99 -Wformat" } */
|
||||
|
||||
#include "format.h"
|
||||
|
||||
struct s {
|
||||
unsigned int u1 : 1;
|
||||
signed int s1 : 1;
|
||||
unsigned int u15 : 15;
|
||||
signed int s15 : 15;
|
||||
unsigned int u16 : 16;
|
||||
signed int s16 : 16;
|
||||
unsigned long u31 : 31;
|
||||
signed long s31 : 31;
|
||||
unsigned long u32 : 32;
|
||||
signed long s32 : 32;
|
||||
unsigned long long u48 : 48;
|
||||
} x;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
printf ("%d%u", x.u1, x.u1);
|
||||
printf ("%d%u", x.s1, x.s1);
|
||||
printf ("%d%u", x.u15, x.u15);
|
||||
printf ("%d%u", x.s15, x.s15);
|
||||
printf ("%d%u", x.u16, x.u16);
|
||||
printf ("%d%u", x.s16, x.s16);
|
||||
printf ("%d%u", x.u31, x.u31);
|
||||
printf ("%d%u", x.s31, x.s31);
|
||||
#if __LONG_MAX__ > 2147483647 && __INT_MAX__ >= 2147483647
|
||||
/* If long is wider than 32 bits, the 32-bit bit-fields are int or
|
||||
unsigned int or promote to those types. Otherwise, long is 32
|
||||
bits and the bit-fields are of type plain long or unsigned
|
||||
long. */
|
||||
printf ("%d%u", x.u32, x.u32);
|
||||
printf ("%d%u", x.s32, x.s32);
|
||||
#else
|
||||
printf ("%ld%lu", x.u32, x.u32);
|
||||
printf ("%ld%lu", x.s32, x.s32);
|
||||
#endif
|
||||
printf ("%llu", x.u48); /* { dg-warning "has type '.*unsigned int:48'" } */
|
||||
printf ("%llu", (unsigned long long)x.u48);
|
||||
}
|
Loading…
Reference in New Issue
Block a user