Message ID | Zk0Lp8yOwmfJv7O1@tucnak |
---|---|
State | New |
Headers | show |
Series | strlen: Fix up !si->full_string_p handling in count_nonzero_bytes_addr [PR115152] | expand |
On Tue, 21 May 2024, Jakub Jelinek wrote: > Hi! > > The following testcase is miscompiled because > strlen_pass::count_nonzero_bytes_addr doesn't handle correctly > the !si->full_string_p case. > If si->full_string_p, it correctly computes minlen and maxlen as > minimum and maximum length of the '\0' terminated stgring and > clears *nulterm (ie. makes sure !full_string_p in the ultimate > caller) if minlen is equal or larger than nbytes and so > '\0' isn't guaranteed to be among those bytes. > But in the !si->full_string_p case, all we know is that there > are [minlen,maxlen] non-zero bytes followed by unknown bytes, > so effectively the maxlen is infinite (but caller cares about only > the first nbytes bytes) and furthermore, we never know if there is > any '\0' char among those, so *nulterm needs to be always cleared. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, > ok for trunk and affected release branches? OK. Richard. > 2024-05-21 Jakub Jelinek <jakub@redhat.com> > > PR tree-optimization/115152 > * tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes_addr): If > !si->full_string_p, clear *nulterm and set maxlen to nbytes. > > * gcc.dg/pr115152.c: New test. > > --- gcc/tree-ssa-strlen.cc.jj 2024-04-29 11:00:45.000000000 +0200 > +++ gcc/tree-ssa-strlen.cc 2024-05-21 13:43:31.031208000 +0200 > @@ -4829,7 +4829,7 @@ strlen_pass::count_nonzero_bytes_addr (t > if (maxlen + 1 < nbytes) > return false; > > - if (nbytes <= minlen) > + if (nbytes <= minlen || !si->full_string_p) > *nulterm = false; > > if (nbytes < minlen) > @@ -4839,6 +4839,9 @@ strlen_pass::count_nonzero_bytes_addr (t > maxlen = nbytes; > } > > + if (!si->full_string_p) > + maxlen = nbytes; > + > if (minlen < lenrange[0]) > lenrange[0] = minlen; > if (lenrange[1] < maxlen) > --- gcc/testsuite/gcc.dg/pr115152.c.jj 2024-05-21 13:46:02.793214348 +0200 > +++ gcc/testsuite/gcc.dg/pr115152.c 2024-05-21 12:49:38.791626073 +0200 > @@ -0,0 +1,17 @@ > +/* PR tree-optimization/115152 */ > +/* { dg-do run } */ > +/* { dg-options "-O3 -fno-tree-fre -fno-tree-dominator-opts -fno-tree-loop-im" } */ > + > +int a, b, c, d; > +signed char e[1] = { 1 }; > + > +int > +main () > +{ > + for (a = 0; a < 3; a++) > + for (b = 0; b < 2; b++) > + c = e[0] = e[0] ^ d; > + if (!c) > + __builtin_abort (); > + return 0; > +} > > Jakub > >
--- gcc/tree-ssa-strlen.cc.jj 2024-04-29 11:00:45.000000000 +0200 +++ gcc/tree-ssa-strlen.cc 2024-05-21 13:43:31.031208000 +0200 @@ -4829,7 +4829,7 @@ strlen_pass::count_nonzero_bytes_addr (t if (maxlen + 1 < nbytes) return false; - if (nbytes <= minlen) + if (nbytes <= minlen || !si->full_string_p) *nulterm = false; if (nbytes < minlen) @@ -4839,6 +4839,9 @@ strlen_pass::count_nonzero_bytes_addr (t maxlen = nbytes; } + if (!si->full_string_p) + maxlen = nbytes; + if (minlen < lenrange[0]) lenrange[0] = minlen; if (lenrange[1] < maxlen) --- gcc/testsuite/gcc.dg/pr115152.c.jj 2024-05-21 13:46:02.793214348 +0200 +++ gcc/testsuite/gcc.dg/pr115152.c 2024-05-21 12:49:38.791626073 +0200 @@ -0,0 +1,17 @@ +/* PR tree-optimization/115152 */ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-tree-fre -fno-tree-dominator-opts -fno-tree-loop-im" } */ + +int a, b, c, d; +signed char e[1] = { 1 }; + +int +main () +{ + for (a = 0; a < 3; a++) + for (b = 0; b < 2; b++) + c = e[0] = e[0] ^ d; + if (!c) + __builtin_abort (); + return 0; +}