mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-18 04:10:23 +08:00
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
This commit is contained in:
parent
92f6e62532
commit
3504b199c2
gcc
@ -1,3 +1,8 @@
|
||||
2003-09-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* c-common.c (c_common_signed_or_unsigned_type): Examine mode,
|
||||
not precision.
|
||||
|
||||
2003-09-22 David Edelsohn <edelsohn@gnu.org>
|
||||
Hartmut Penner <hpenner@de.ibm.com>
|
||||
|
||||
|
@ -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;
|
||||
|
30
gcc/testsuite/g++.dg/opt/enum1.C
Normal file
30
gcc/testsuite/g++.dg/opt/enum1.C
Normal file
@ -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<E>(*x);
|
||||
switch (e)
|
||||
{
|
||||
case test:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char dummy = test;
|
||||
if (! foo(&dummy))
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user