This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
underlying type of C++ enums
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 25 Apr 2002 19:01:38 -0300
- Subject: underlying type of C++ enums
- Organization: GCC Team, Red Hat
The underlying type we choose for the following enum is `int', not
`unsigned [long] long' as one might expect from the Standard C++
requirements. (Note that the rules for Standard C are different)
enum foo
{
foo1 = 0,
foo2 = 0xffffffffffffffffULL,
foo3 = 0xf0fffffffffffffeULL,
};
The problem is that, when we look for the min and max enumerators, we
use tree_int_cst_lt, that assumes both operands have the same value
for the UNSIGNED flag. In the case of enum initializers, this
assumption does not hold.
This patch fixes the problem.
I recommend this patch to be considered for GCC 3.1, since it has ABI
affects (it would change sizeof foo from sizeof int to sizeof long
long).
Ok to install?
Index: gcc/cp/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* decl.c (finish_enum): Take the sign of each enumerator into
account when looking for the minimum and maximum values.
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.902
diff -u -p -r1.902 decl.c
--- gcc/cp/decl.c 24 Apr 2002 20:41:01 -0000 1.902
+++ gcc/cp/decl.c 25 Apr 2002 22:01:09 -0000
@@ -13210,7 +13210,9 @@ finish_enum (enumtype)
{
tree pair;
tree minnode;
+ int minnode_sgn;
tree maxnode;
+ int maxnode_sgn;
tree t;
bool unsignedp;
int lowprec;
@@ -13242,35 +13244,57 @@ finish_enum (enumtype)
}
/* Figure out what the minimum and maximum values of the enumerators
- are. */
+ are. We have to take the sign of each constant into account when
+ comparing with minnode and maxnode, because tree_int_cst_lt
+ assumes both operands have the same value for the UNSIGNED
+ flag. */
if (TYPE_VALUES (enumtype))
{
minnode = maxnode = NULL_TREE;
+ minnode_sgn = maxnode_sgn = 0;
for (pair = TYPE_VALUES (enumtype);
pair;
pair = TREE_CHAIN (pair))
{
tree value;
+ int value_sgn;
value = DECL_INITIAL (TREE_VALUE (pair));
+ value_sgn = tree_int_cst_sgn (value);
if (!minnode)
- minnode = maxnode = value;
- else if (tree_int_cst_lt (maxnode, value))
- maxnode = value;
- else if (tree_int_cst_lt (value, minnode))
- minnode = value;
+ {
+ minnode = maxnode = value;
+ minnode_sgn = maxnode_sgn = value_sgn;
+ }
+ else if (maxnode_sgn < value_sgn
+ || (maxnode_sgn == value_sgn
+ && tree_int_cst_lt (maxnode, value)))
+ {
+ maxnode = value;
+ maxnode_sgn = value_sgn;
+ }
+ else if (value_sgn < minnode_sgn
+ || (value_sgn == minnode_sgn
+ && tree_int_cst_lt (value, minnode)))
+ {
+ minnode = value;
+ minnode_sgn = value_sgn;
+ }
}
}
else
- minnode = maxnode = integer_zero_node;
+ {
+ minnode = maxnode = integer_zero_node;
+ minnode_sgn = maxnode_sgn = 0;
+ }
/* Compute the number of bits require to represent all values of the
enumeration. We must do this before the type of MINNODE and
MAXNODE are transformed, since min_precision relies on the
TREE_TYPE of the value it is passed. */
- unsignedp = tree_int_cst_sgn (minnode) >= 0;
+ unsignedp = minnode_sgn >= 0;
lowprec = min_precision (minnode, unsignedp);
highprec = min_precision (maxnode, unsignedp);
precision = MAX (lowprec, highprec);
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer