tree prev_value;
bool overflowed;
- /* The next value is the previous value plus one.
- add_double doesn't know the type of the target expression,
- so we must check with int_fits_type_p as well. */
+ /* C++03 7.2/4: If no initializer is specified for the first
+ enumerator, the type is an unspecified integral
+ type. Otherwise the type is the same as the type of the
+ initializing value of the preceding enumerator unless the
+ incremented value is not representable in that type, in
+ which case the type is an unspecified integral type
+ sufficient to contain the incremented value. */
prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
if (error_operand_p (prev_value))
value = error_mark_node;
overflowed = add_double (TREE_INT_CST_LOW (prev_value),
TREE_INT_CST_HIGH (prev_value),
1, 0, &lo, &hi);
- value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
- overflowed
- |= !int_fits_type_p (value, TREE_TYPE (prev_value));
+ if (!overflowed)
+ {
+ double_int di;
+ tree type = TREE_TYPE (prev_value);
+ bool pos = (TYPE_UNSIGNED (type) || hi >= 0);
+ di.low = lo; di.high = hi;
+ if (!double_int_fits_to_tree_p (type, di))
+ {
+ unsigned int itk;
+ for (itk = itk_int; itk != itk_none; itk++)
+ {
+ type = integer_types[itk];
+ if (type != NULL_TREE
+ && (pos || !TYPE_UNSIGNED (type))
+ && double_int_fits_to_tree_p (type, di))
+ break;
+ }
+ if (type && cxx_dialect < cxx0x
+ && itk > itk_unsigned_long)
+ pedwarn (input_location, OPT_Wlong_long, pos ? "\
+incremented enumerator value is too large for %<unsigned long%>" : "\
+incremented enumerator value is too large for %<long%>");
+ }
+ if (type == NULL_TREE)
+ overflowed = true;
+ else
+ value = double_int_to_tree (type, di);
+ }
if (overflowed)
{