Commit 3504b199 by Richard Henderson Committed by Richard Henderson

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
parent 92f6e625
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;
......
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment