Hi,
this fixes the cd2a31a regression in the ACATS testsuite on 32-bit targets
introduced by the recent change to get_array_ctor_element_at_index:
* fold-const.h (get_array_ctor_element_at_index): Adjust.
* fold-const.c (get_array_ctor_element_at_index): Add
ctor_idx output parameter informing the caller where in
the constructor the element was (not) found. Add early exit
for when the ctor is sorted.
This change overlooks that the index can wrap around during the traversal of
the CONSTRUCTOR and therefore causes the function to return bogus values as
soon as this happens. Moreover, given this chunk of added code:
else if (in_gimple_form)
/* We're past the element we search for. Note during parsing
the elements might not be sorted.
??? We should use a binary search and a flag on the
CONSTRUCTOR as to whether elements are sorted in declaration
order. */
break;
I would respectfully suggest that the author thinks about redoing things from
scratch here. In the meantime, the attached patch kludges around the issue.
Tested on x86_64-suse-linux, OK for the mainline?
2019-08-01 Eric Botcazou <ebotca...@adacore.com>
PR tree-optimization/91169
* fold-const.c (get_array_ctor_element_at_index): Remove early exit and
do not return a bogus ctor_idx when the index wraps around.
--
Eric Botcazou
Index: fold-const.c
===================================================================
--- fold-const.c (revision 273907)
+++ fold-const.c (working copy)
@@ -11841,9 +11841,9 @@ fold_ternary_loc (location_t loc, enum tree_code c
/* Gets the element ACCESS_INDEX from CTOR, which must be a CONSTRUCTOR
of an array (or vector). *CTOR_IDX if non-NULL is updated with the
constructor element index of the value returned. If the element is
- not found NULL_TREE is returned and *CTOR_IDX is updated to
- the index of the element after the ACCESS_INDEX position (which
- may be outside of the CTOR array). */
+ not found, then NULL_TREE is returned and *CTOR_IDX is updated to
+ the index of the element after the ACCESS_INDEX position (which may
+ be outside of the CTOR array). */
tree
get_array_ctor_element_at_index (tree ctor, offset_int access_index,
@@ -11874,8 +11874,9 @@ get_array_ctor_element_at_index (tree ctor, offset
TYPE_SIGN (index_type));
offset_int max_index;
- unsigned cnt;
+ unsigned cnt, after_cnt;
tree cfield, cval;
+ bool after_cnt_valid = false;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
{
@@ -11895,10 +11896,15 @@ get_array_ctor_element_at_index (tree ctor, offset
}
else
{
+ const offset_int old_index = index;
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),
+ TYPE_SIGN (index_type));
+ if (wi::cmpu (index, old_index) <= 0)
+ after_cnt_valid = false;
+ }
max_index = index;
}
@@ -11912,16 +11918,20 @@ get_array_ctor_element_at_index (tree ctor, offset
return cval;
}
}
- else if (in_gimple_form)
- /* We're past the element we search for. Note during parsing
- the elements might not be sorted.
- ??? We should use a binary search and a flag on the
- CONSTRUCTOR as to whether elements are sorted in declaration
- order. */
- break;
+
+ /* We may be past the element we search for. Note that during parsing
+ the elements might not be sorted. Note also that the index may wrap
+ around during the traversal of the constructor if it was signed.
+ ??? We should use a binary search and a flag on the CONSTRUCTOR as
+ to whether elements are sorted in declaration order. */
+ else if (in_gimple_form && !after_cnt_valid)
+ {
+ after_cnt = cnt;
+ after_cnt_valid = true;
+ }
}
if (ctor_idx)
- *ctor_idx = cnt;
+ *ctor_idx = after_cnt_valid ? after_cnt : cnt;
return NULL_TREE;
}