From: Jakub Jelinek Date: Tue, 12 Mar 2024 09:23:19 +0000 (+0100) Subject: strlen: Fix another spot that can create invalid ranges [PR114293] X-Git-Tag: basepoints/gcc-15~702 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=39737cdf002637c7a652e9c3e36f369cfce581e5;p=gcc.git strlen: Fix another spot that can create invalid ranges [PR114293] This PR is similar to PR110603 fixed with r14-8487, except in a different spot. From the memset with -1 size of non-zero value we determine minimum of (size_t) -1 and the code uses PTRDIFF_MAX - 2 (not really sure I understand why it is - 2 and not - 1, e.g. heap allocated array with PTRDIFF_MAX char elements which contain '\0' in the last element should be fine, no? One can still represent arr[PTRDIFF_MAX] - arr[0] and arr[0] - arr[PTRDIFF_MAX] in ptrdiff_t and strlen (arr) == PTRDIFF_MAX - 1) as the maximum, so again invalid range. As in the other case, it is just UB that can lead to that, and we have choice to only keep the min and use +inf for max, or only keep max and use 0 for min, or not set the range at all, or use [min, min] or [max, max] etc. The following patch uses [min, +inf]. 2024-03-12 Jakub Jelinek PR tree-optimization/114293 * tree-ssa-strlen.cc (strlen_pass::handle_builtin_strlen): If max is smaller than min, set max to ~(size_t)0. * gcc.dg/pr114293.c: New test. --- diff --git a/gcc/testsuite/gcc.dg/pr114293.c b/gcc/testsuite/gcc.dg/pr114293.c new file mode 100644 index 00000000000..eb49ede0657 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114293.c @@ -0,0 +1,10 @@ +/* PR tree-optimization/114293 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -w" } */ + +int +foo (int x) +{ + __builtin_memset (&x, 5, -1); + return __builtin_strlen ((char *) &x); +} diff --git a/gcc/tree-ssa-strlen.cc b/gcc/tree-ssa-strlen.cc index 20540c52948..e09c9cc081f 100644 --- a/gcc/tree-ssa-strlen.cc +++ b/gcc/tree-ssa-strlen.cc @@ -2341,6 +2341,8 @@ strlen_pass::handle_builtin_strlen () wide_int min = wi::to_wide (old); wide_int max = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2; + if (wi::gtu_p (min, max)) + max = wi::to_wide (TYPE_MAX_VALUE (TREE_TYPE (lhs))); set_strlen_range (lhs, min, max); } else