PR 80769: Incorrect strlen optimisation
In this testcase, we (correctly) record after:
strcpy (p1, "abcde");
char *p2 = strchr (p1, '\0');
strcpy (p2, q);
that the length of p1 and p2 can be calculated by converting the
second strcpy to:
tmp = stpcpy (p2, q)
and then doing tmp - p1 for p1 and tmp - p2 for p2. This is delayed
until we know whether we actually need it. Then:
char *p3 = strchr (p2, '\0');
forces us to calculate the length of p2 in this way. At this point
we had three related strinfos:
p1: delayed length, calculated from tmp = stpcpy (p2, q)
p2: known length, tmp - p2
p3: known length, 0
After:
memcpy (p3, "x", 2);
we use adjust_related_strinfos to add 1 to each length. However,
that didn't do anything for delayed lengths because:
else if (si->stmt != NULL)
/* Delayed length computation is unaffected. */
;
So after the memcpy we had:
p1: delayed length, calculated from tmp = stpcpy (p2, q)
p2: known length, tmp - p2 + 1
p3: known length, 1
where the length of p1 was no longer correct.
2017-05-16 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
PR tree-optimization/80769
* tree-ssa-strlen.c (strinfo): Document that "stmt" is also used
for malloc and calloc. Document the new invariant that all related
strinfos have delayed lengths or none do.
(verify_related_strinfos): Move earlier in file.
(set_endptr_and_length): New function, split out from...
(get_string_length): ...here. Also set the lengths of related
strinfos.
(zero_length_string): Assert that chainsi has known (rather than
delayed) lengths.
(adjust_related_strinfos): Likewise.
gcc/testsuite/
PR tree-optimization/80769
* gcc.dg/strlenopt-31.c: New test.
* gcc.dg/strlenopt-31g.c: Likewise.
From-SVN: r249879