aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2005-07-16 17:01:57 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2005-07-16 17:01:57 +0100
commit0b359b010308064ecce067200e66662b354d3b7d (patch)
tree5f32a34bba8e5b6ed4a7e93f9ba7f8ff1df01cd4 /gcc/c-decl.c
parent8fcef540f3a1600c26bc7dbebed9c6142f3da7e8 (diff)
downloadgcc-0b359b010308064ecce067200e66662b354d3b7d.zip
gcc-0b359b010308064ecce067200e66662b354d3b7d.tar.gz
gcc-0b359b010308064ecce067200e66662b354d3b7d.tar.bz2
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
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 67c72a5..aff59bc1 100644
--- a/gcc/c-decl.c
+++ b/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;