unsigned *ctor_idx)
{
tree index_type = NULL_TREE;
+ signop index_sgn = UNSIGNED;
offset_int low_bound = 0;
if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
/* Static constructors for variably sized objects makes no sense. */
gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
- low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
+ /* ??? When it is obvious that the range is signed, treat it so. */
+ if (TYPE_UNSIGNED (index_type)
+ && TYPE_MAX_VALUE (domain_type)
+ && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type),
+ TYPE_MIN_VALUE (domain_type)))
+ {
+ index_sgn = SIGNED;
+ low_bound
+ = offset_int::from (wi::to_wide (TYPE_MIN_VALUE (domain_type)),
+ SIGNED);
+ }
+ else
+ {
+ index_sgn = TYPE_SIGN (index_type);
+ low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
+ }
}
}
if (index_type)
access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index_sgn);
- offset_int index = low_bound - 1;
+ offset_int index = low_bound;
if (index_type)
- index = wi::ext (index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
- offset_int max_index;
+ offset_int max_index = index;
unsigned cnt;
tree cfield, cval;
+ bool first_p = true;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
{
if (cfield)
{
if (TREE_CODE (cfield) == INTEGER_CST)
- max_index = index = wi::to_offset (cfield);
+ max_index = index
+ = offset_int::from (wi::to_wide (cfield), index_sgn);
else
{
gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
- index = wi::to_offset (TREE_OPERAND (cfield, 0));
- max_index = wi::to_offset (TREE_OPERAND (cfield, 1));
+ index = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 0)),
+ index_sgn);
+ max_index
+ = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 1)),
+ index_sgn);
+ gcc_checking_assert (wi::le_p (index, max_index, index_sgn));
}
}
- else
+ else if (!first_p)
{
- index += 1;
+ index = max_index + 1;
if (index_type)
- index = wi::ext (index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
+ gcc_checking_assert (wi::gt_p (index, max_index, index_sgn));
max_index = index;
}
+ else
+ first_p = false;
/* Do we have match? */
- if (wi::cmpu (access_index, index) >= 0)
+ if (wi::cmp (access_index, index, index_sgn) >= 0)
{
- if (wi::cmpu (access_index, max_index) <= 0)
+ if (wi::cmp (access_index, max_index, index_sgn) <= 0)
{
if (ctor_idx)
*ctor_idx = cnt;