]> gcc.gnu.org Git - gcc.git/commitdiff
strlen: Fix another spot that can create invalid ranges [PR114293]
authorJakub Jelinek <jakub@redhat.com>
Tue, 12 Mar 2024 09:23:19 +0000 (10:23 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 12 Mar 2024 09:23:19 +0000 (10:23 +0100)
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  <jakub@redhat.com>

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.

gcc/testsuite/gcc.dg/pr114293.c [new file with mode: 0644]
gcc/tree-ssa-strlen.cc

diff --git a/gcc/testsuite/gcc.dg/pr114293.c b/gcc/testsuite/gcc.dg/pr114293.c
new file mode 100644 (file)
index 0000000..eb49ede
--- /dev/null
@@ -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);
+}
index 20540c5294824837745909f489d1797c901baf08..e09c9cc081f5bb59403123ef0fc7c8a24ac5cfc2 100644 (file)
@@ -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
This page took 0.0685 seconds and 5 git commands to generate.