On 07/17/2018 09:19 AM, Martin Sebor wrote:
My enhancement to extract constant strings out of complex
aggregates committed last week introduced a couple of bugs in
dealing with non-constant indices and offsets. One of the bugs
was fixed earlier today (PR 86528) but another one remains. It
causes strlen (among other functions) to incorrectly fold
expressions involving a non-constant index into an array of
strings by treating the index the same as a non-consatnt
offset into it.
The non-constant index should either prevent the folding, or it
needs to handle it differently from an offset.
The attached patch takes the conservative approach of avoiding
the folding in this case. The remaining changes deal with
the fallout from the fix.
Tested on x86_64-linux.
Martin
gcc-86532.diff
PR tree-optimization/86532 - Wrong code due to a wrong strlen folding starting with r262522
gcc/ChangeLog:
PR tree-optimization/86532
* builtins.c (c_strlen): Correct handling of non-constant offsets.
(check_access): Be prepared for non-constant length ranges.
* expr.c (string_constant): Only handle the minor non-constant
array index.
gcc/testsuite/ChangeLog:
PR tree-optimization/86532
* gcc.c-torture/execute/strlen-2.c: New test.
[ ... ]
Index: gcc/expr.c
===================================================================
--- gcc/expr.c (revision 262764)
+++ gcc/expr.c (working copy)
@@ -11343,16 +11356,15 @@ string_constant (tree arg, tree *ptr_offset)
{
if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
return NULL_TREE;
- if (tree eltsize = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array))))
- {
- /* Add the scaled variable index to the constant offset. */
- tree eltoff = fold_build2 (MULT_EXPR, TREE_TYPE (offset),
- fold_convert (sizetype, varidx),
- eltsize);
- offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, eltoff);
- }
- else
- return NULL_TREE;
+
+ while (TREE_CODE (chartype) != INTEGER_TYPE)
+ chartype = TREE_TYPE (chartype);
This is a bit concerning. First under what conditions is chartype not
going to be an INTEGER_TYPE? And under what conditions will extracting
its type ultimately lead to something that is an INTEGER_TYPE?