diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-08 08:45:05 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-08 08:45:05 +0000 |
commit | 4f7f7efd45b15639029ff88aa51f27e284dd381c (patch) | |
tree | 69763a66482d42b14599835106ea027f80e7499e /gcc/c-common.c | |
parent | 07648566379bd442b9bd7479f77c16ad431c8a82 (diff) | |
download | gcc-4f7f7efd45b15639029ff88aa51f27e284dd381c.tar.gz |
2004-07-08 Joseph S. Myers <jsm@polyomino.org.uk>
Neil Booth <neil@daikokuya.co.uk>
PR c/2511
PR c/3325
* c-decl.c (finish_struct): Ensure bit-fields are given the
correct type.
* c-common.c (c_common_signed_or_unsigned_type): For C, require
the precision to match as well as the mode.
* expr.c (reduce_to_bit_field_precision): New function.
(expand_expr_real_1): Reduce expressions of bit-field type to
proper precision.
* langhooks.h (reduce_bit_field_operations): New hook.
* langhooks-def.h (LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS):
Define.
* c-lang.c, objc/objc-lang.c
(LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS): Define.
* objc/objc-act.c (check_ivars): Convert types to bit-field types
before checking.
* tree.c (build_nonstandard_integer_type): New function.
* tree.h (build_nonstandard_integer_type): New prototype.
* tree-ssa.c (tree_ssa_useless_type_conversion_1): Don't treat
conversions between integer and boolean types as useless.
testsuite:
* gcc.c-torture/execute/bitfld-1.x: Remove.
* gcc.c-torture/execute/bitfld-3.c: New test.
* gcc.dg/bitfld-2.c: Remove XFAILs.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84279 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 9a8039b9431..ebb5e65e404 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1636,40 +1636,51 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) || TYPE_UNSIGNED (type) == unsignedp) return type; - /* Must check the mode of the types, not the precision. Enumeral types - in C++ have precision set to match their range, but may use a wider - mode to match an ABI. If we change modes, we may wind up with bad - conversions. */ - - if (TYPE_MODE (type) == TYPE_MODE (signed_char_type_node)) + /* For ENUMERAL_TYPEs in C++, must check the mode of the types, not + the precision; they have precision set to match their range, but + may use a wider mode to match an ABI. If we change modes, we may + wind up with bad conversions. For INTEGER_TYPEs in C, must check + the precision as well, so as to yield correct results for + bit-field types. C++ does not have these separate bit-field + types, and producing a signed or unsigned variant of an + ENUMERAL_TYPE may cause other problems as well. */ + +#define TYPE_OK(node) \ + (TYPE_MODE (type) == TYPE_MODE (node) \ + && (c_dialect_cxx () || TYPE_PRECISION (type) == TYPE_PRECISION (node))) + if (TYPE_OK (signed_char_type_node)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_MODE (type) == TYPE_MODE (integer_type_node)) + if (TYPE_OK (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_MODE (type) == TYPE_MODE (short_integer_type_node)) + if (TYPE_OK (short_integer_type_node)) return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_MODE (type) == TYPE_MODE (long_integer_type_node)) + if (TYPE_OK (long_integer_type_node)) return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_MODE (type) == TYPE_MODE (long_long_integer_type_node)) + if (TYPE_OK (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (TYPE_MODE (type) == TYPE_MODE (widest_integer_literal_type_node)) + if (TYPE_OK (widest_integer_literal_type_node)) return (unsignedp ? widest_unsigned_literal_type_node : widest_integer_literal_type_node); #if HOST_BITS_PER_WIDE_INT >= 64 - if (TYPE_MODE (type) == TYPE_MODE (intTI_type_node)) + if (TYPE_OK (intTI_type_node)) return unsignedp ? unsigned_intTI_type_node : intTI_type_node; #endif - if (TYPE_MODE (type) == TYPE_MODE (intDI_type_node)) + if (TYPE_OK (intDI_type_node)) return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - if (TYPE_MODE (type) == TYPE_MODE (intSI_type_node)) + if (TYPE_OK (intSI_type_node)) return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - if (TYPE_MODE (type) == TYPE_MODE (intHI_type_node)) + if (TYPE_OK (intHI_type_node)) return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - if (TYPE_MODE (type) == TYPE_MODE (intQI_type_node)) + if (TYPE_OK (intQI_type_node)) return unsignedp ? unsigned_intQI_type_node : intQI_type_node; +#undef TYPE_OK - return type; + if (c_dialect_cxx ()) + return type; + else + return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); } /* The C version of the register_builtin_type langhook. */ |