This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/80769] Invalid delayed string length computation in tree-ssa-strlen.c


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80769

--- Comment #2 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> ---
Author: rsandifo
Date: Sun Jul  2 08:43:11 2017
New Revision: 249879

URL: https://gcc.gnu.org/viewcvs?rev=249879&root=gcc&view=rev
Log:
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.

Added:
    trunk/gcc/testsuite/gcc.dg/strlenopt-31.c
    trunk/gcc/testsuite/gcc.dg/strlenopt-31g.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-ssa-strlen.c

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]