diff mbox series

strlen: Fix another spot that can create invalid ranges [PR114293]

Message ID ZfASkBVhrjzvb4Py@tucnak
State New
Headers show
Series strlen: Fix another spot that can create invalid ranges [PR114293] | expand

Commit Message

Jakub Jelinek March 12, 2024, 8:30 a.m. UTC
Hi!

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].

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

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.


	Jakub

Comments

Richard Biener March 12, 2024, 8:35 a.m. UTC | #1
On Tue, 12 Mar 2024, Jakub Jelinek wrote:

> Hi!
> 
> 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].
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 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/tree-ssa-strlen.cc.jj	2024-01-30 09:57:58.361809262 +0100
> +++ gcc/tree-ssa-strlen.cc	2024-03-11 10:35:04.305650520 +0100
> @@ -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
> --- gcc/testsuite/gcc.dg/pr114293.c.jj	2024-03-11 10:41:04.375708877 +0100
> +++ gcc/testsuite/gcc.dg/pr114293.c	2024-03-11 10:40:50.355895196 +0100
> @@ -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);
> +}
> 
> 	Jakub
> 
>
diff mbox series

Patch

--- gcc/tree-ssa-strlen.cc.jj	2024-01-30 09:57:58.361809262 +0100
+++ gcc/tree-ssa-strlen.cc	2024-03-11 10:35:04.305650520 +0100
@@ -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
--- gcc/testsuite/gcc.dg/pr114293.c.jj	2024-03-11 10:41:04.375708877 +0100
+++ gcc/testsuite/gcc.dg/pr114293.c	2024-03-11 10:40:50.355895196 +0100
@@ -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);
+}