From 3504b199c283afd4d48cbd0f786fa6fd33a11a13 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 22 Sep 2003 23:04:14 -0700 Subject: [PATCH] c-common.c (c_common_signed_or_unsigned_type): Examine mode, not precision. * c-common.c (c_common_signed_or_unsigned_type): Examine mode, not precision. * g++.dg/opt/enum1.C: New. From-SVN: r71677 --- gcc/ChangeLog | 5 +++++ gcc/c-common.c | 27 ++++++++++++++++----------- gcc/testsuite/g++.dg/opt/enum1.C | 30 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/enum1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7b8b49bd62..2dd2543bb5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2003-09-22 Richard Henderson + + * c-common.c (c_common_signed_or_unsigned_type): Examine mode, + not precision. + 2003-09-22 David Edelsohn Hartmut Penner diff --git a/gcc/c-common.c b/gcc/c-common.c index 39c6a5741b5..905ad9316c3 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1982,32 +1982,37 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type) || TREE_UNSIGNED (type) == unsignedp) return type; - if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) + /* 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)) return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (integer_type_node)) return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (short_integer_type_node)) return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (long_integer_type_node)) return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (long_long_integer_type_node)) return (unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node); - if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (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_PRECISION (type) == TYPE_PRECISION (intTI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intTI_type_node)) return unsignedp ? unsigned_intTI_type_node : intTI_type_node; #endif - if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intDI_type_node)) return unsignedp ? unsigned_intDI_type_node : intDI_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intSI_type_node)) return unsignedp ? unsigned_intSI_type_node : intSI_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (intHI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intHI_type_node)) return unsignedp ? unsigned_intHI_type_node : intHI_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node)) + if (TYPE_MODE (type) == TYPE_MODE (intQI_type_node)) return unsignedp ? unsigned_intQI_type_node : intQI_type_node; return type; diff --git a/gcc/testsuite/g++.dg/opt/enum1.C b/gcc/testsuite/g++.dg/opt/enum1.C new file mode 100644 index 00000000000..6416b3f1b86 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/enum1.C @@ -0,0 +1,30 @@ +// Verify that we don't confuse precision and mode for enums. +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort(); + +enum E { + zero = 0, + test = 0xbb +}; + +static bool foo(unsigned char *x) +{ + E e = static_cast(*x); + switch (e) + { + case test: + return true; + default: + return false; + } +} + +int main() +{ + unsigned char dummy = test; + if (! foo(&dummy)) + abort (); + return 0; +} -- 2.30.2