[Bug tree-optimization/96758] [10/11 Regression] strncmp miscompiles as memcmp since r10-3920-g27c14dbc6b01d5b7

cvs-commit at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Aug 25 17:45:38 GMT 2020


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

--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-10 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:0dbfa88edafbe913a7a9099246041e0190aa3948

commit r10-8670-g0dbfa88edafbe913a7a9099246041e0190aa3948
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Aug 25 13:47:10 2020 +0200

    strlen: Fix handle_builtin_string_cmp [PR96758]

    The following testcase is miscompiled, because handle_builtin_string_cmp
    sees a strncmp call with constant last argument 4, where one of the strings
    has an upper bound of 5 bytes (due to it being an array of that size) and
    the other has a known string length of 1 and the result is used only in
    equality comparison.
    It is folded into __builtin_strncmp_eq (str1, str2, 4), which is
    incorrect, because that means reading 4 bytes from both strings and
    comparing that.  When one of the strings has known strlen of 1, we want to
    compare just 2 bytes, not 4, as strncmp shouldn't compare any bytes beyond
    the null.
    So, the last argument to __builtin_strncmp_eq should be the minimum of the
    provided strncmp last argument and the known string length + 1 (assuming
    the other string has only a known upper bound due to array size).

    Besides that, I've noticed the code has been written with the intent to
also
    support the case where we know exact string length of both strings (but not
    the string content, so we can't compute it at compile time).  In that case,
    both cstlen1 and cstlen2 are non-negative and both arysiz1 and arysiz2 are
    negative.  We wouldn't optimize that, cmpsiz would be either the strncmp
    last argument, or for strcmp the first string length, but varsiz would be
    -1 and thus cmpsiz would be never < varsiz.  The patch fixes it by using
the
    correct length, in that case using the minimum of the two and for strncmp
    also the last argument.

    2020-08-25  Jakub Jelinek  <jakub@redhat.com>

            PR tree-optimization/96758
            * tree-ssa-strlen.c (handle_builtin_string_cmp): If both cstlen1
            and cstlen2 are set, set cmpsiz to their minimum, otherwise use the
            one that is set.  If bound is used and smaller than cmpsiz, set
cmpsiz
            to bound.  If both cstlen1 and cstlen2 are set, perform the
optimization.

            * gcc.dg/strcmpopt_12.c: New test.

    (cherry picked from commit f982a6ec9b6d98f5f37114b1d7455c54ce5056b8)


More information about the Gcc-bugs mailing list