diff mbox series

Fix PR 86572

Message ID VI1PR0701MB2862DEE3CE9F931132E8ECDDE4F40@VI1PR0701MB2862.eurprd07.prod.outlook.com
State New
Headers show
Series Fix PR 86572 | expand

Commit Message

Bernd Edlinger Oct. 22, 2018, 3:08 p.m. UTC
Hi!

This makes c_strlen avoid an unsafe strlen folding of const arguments
with non-const offset.  Currently a negative out of bounds offset
makes the strlen function return an extremely large number, and
at the same time, prevents the VRP machinery, to determine the correct
range if the strlen function in this case.

Fixed by doing the whole computation in size_t and casting the
result back to ssize_t.


Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.

Comments

Martin Sebor Oct. 22, 2018, 7:03 p.m. UTC | #1
On 10/22/2018 09:08 AM, Bernd Edlinger wrote:
> Hi!
>
> This makes c_strlen avoid an unsafe strlen folding of const arguments
> with non-const offset.  Currently a negative out of bounds offset
> makes the strlen function return an extremely large number, and
> at the same time, prevents the VRP machinery, to determine the correct
> range if the strlen function in this case.
>
> Fixed by doing the whole computation in size_t and casting the
> result back to ssize_t.
>
>
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?

In general, I view folding to a "safe" value as done in this patch
(and as Richard suggests in his comment on the bug) far preferable
-- as in far safer/more secure -- to avoiding folding in these
cases (currently the prevailing strategy).

If there is consensus on adopting this approach for strlen I'd like
to see it applied in other such cases as well as a matter of policy.

Some other similar examples to consider include:

  *  calling other built-ins on such arrays, including strnlen,
     memchr/strchr, and strpbrk
  *  indexing into such an array (note that accesses at constant
     out-of-bounds indices into constant arrays are already folded
     to zero, although that may be an accidental rather than
     a conscious decision made to avoid the worst kind of fallout).

None of these is currently folded to a safe value.  GCC calls
the library functions for the built-ins in the first bullet when
the argument is a constant string with a non-constant offset,
even though it could fold them.

At some point it would be also helpful to try to get consensus
on whether emitting a trap in these cases (perhaps under
an option) is something to start moving toward, as we discussed
at Cauldron.

Martin
Bernd Edlinger Oct. 27, 2018, 12:49 p.m. UTC | #2
On 10/22/18 9:03 PM, Martin Sebor wrote:
> On 10/22/2018 09:08 AM, Bernd Edlinger wrote:
>> Hi!
>>
>> This makes c_strlen avoid an unsafe strlen folding of const arguments
>> with non-const offset.  Currently a negative out of bounds offset
>> makes the strlen function return an extremely large number, and
>> at the same time, prevents the VRP machinery, to determine the correct
>> range if the strlen function in this case.
>>
>> Fixed by doing the whole computation in size_t and casting the
>> result back to ssize_t.
>>
>>
>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>> Is it OK for trunk?
> 
> In general, I view folding to a "safe" value as done in this patch
> (and as Richard suggests in his comment on the bug) far preferable
> -- as in far safer/more secure -- to avoiding folding in these
> cases (currently the prevailing strategy).
> 

Well, in this case we have the slightly different situation,
where 'strlen(string_cst + x)' is folded to 'x <= len ? len - x : 0'.
The string_cst does not have embedded nuls, and may be declared
like 'const char string_cst[100] = "string"'.

So the COND_EXPR is not there to separate valid from invalid inputs,
but instead we may assume that x does never exceed the array bounds.

However it still results in more accurate range infos, to do all
computations in unsigned arithmetics, and a slightly more safe result
if the x is negative at the same time, so win-win.

But I have no doubt that it would be even more safe to have a trap
if x is out of bounds, however if we add another conditional branch,
that would be something that needs to be optional, and results in
slightly less efficient code.


> If there is consensus on adopting this approach for strlen I'd like
> to see it applied in other such cases as well as a matter of policy.
> 
> Some other similar examples to consider include:
> 
>   *  calling other built-ins on such arrays, including strnlen,
>      memchr/strchr, and strpbrk
>   *  indexing into such an array (note that accesses at constant
>      out-of-bounds indices into constant arrays are already folded
>      to zero, although that may be an accidental rather than
>      a conscious decision made to avoid the worst kind of fallout).
> 

I would argue that if the undefinedness of any such construct can be
determined statically, there should be a warning, and the folding
should not be done, the out-of-bounds index handling is also something
that I would remove eventually.  The folding should not be done
when it is evident that the index exceeds the memory size, as returned
by string_constant, while it is still okay to fold to 0, if the index is
somewhere in between the string length and the memory size.
That can be determined statically, and comes at no extra cost.


Bernd.
Bernd Edlinger Nov. 1, 2018, 3:15 p.m. UTC | #3
Ping...

For this patch here: https://gcc.gnu.org/ml/gcc-patches/2018-10/msg01336.html

Thanks
Bernd.

On 10/22/18 5:08 PM, Bernd Edlinger wrote:
> Hi!
> 
> This makes c_strlen avoid an unsafe strlen folding of const arguments
> with non-const offset.  Currently a negative out of bounds offset
> makes the strlen function return an extremely large number, and
> at the same time, prevents the VRP machinery, to determine the correct
> range if the strlen function in this case.
> 
> Fixed by doing the whole computation in size_t and casting the
> result back to ssize_t.
> 
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?
> 
> 
> Thanks
> Bernd.
Jeff Law Nov. 4, 2018, 6:02 p.m. UTC | #4
On 10/22/18 9:08 AM, Bernd Edlinger wrote:
> Hi!
> 
> This makes c_strlen avoid an unsafe strlen folding of const arguments
> with non-const offset.  Currently a negative out of bounds offset
> makes the strlen function return an extremely large number, and
> at the same time, prevents the VRP machinery, to determine the correct
> range if the strlen function in this case.
> 
> Fixed by doing the whole computation in size_t and casting the
> result back to ssize_t.
> 
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?
> 
> 
> Thanks
> Bernd.
> 
> 
> patch-pr86572.diff
> 
> gcc:
> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> 
> 	PR tree-optimization/86572
> 	* builtins.c (c_strlen): Handle negative offsets in a safe way.
> 
> testsuite:
> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> 
> 	PR tree-optimization/86572
> 	* gcc.dg/pr86572.c: New test.
OK.
jeff
H.J. Lu Nov. 5, 2018, 12:28 a.m. UTC | #5
On Sun, Nov 4, 2018 at 10:02 AM Jeff Law <law@redhat.com> wrote:
>
> On 10/22/18 9:08 AM, Bernd Edlinger wrote:
> > Hi!
> >
> > This makes c_strlen avoid an unsafe strlen folding of const arguments
> > with non-const offset.  Currently a negative out of bounds offset
> > makes the strlen function return an extremely large number, and
> > at the same time, prevents the VRP machinery, to determine the correct
> > range if the strlen function in this case.
> >
> > Fixed by doing the whole computation in size_t and casting the
> > result back to ssize_t.
> >
> >
> > Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> > Is it OK for trunk?
> >
> >
> > Thanks
> > Bernd.
> >
> >
> > patch-pr86572.diff
> >
> > gcc:
> > 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> >
> >       PR tree-optimization/86572
> >       * builtins.c (c_strlen): Handle negative offsets in a safe way.
> >
> > testsuite:
> > 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> >
> >       PR tree-optimization/86572
> >       * gcc.dg/pr86572.c: New test.
> OK.
> jeff

This caused:

/export/gnu/import/git/gcc-test-ia32/src-trunk/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c:56:1:
internal compiler error: verify_gimple failed^M
0x8922dc4 verify_gimple_in_seq(gimple*)^M
        ../../src-trunk/gcc/tree-cfg.c:5082^M
0x86899d7 gimplify_body(tree_node*, bool)^M
        ../../src-trunk/gcc/gimplify.c:12859^M
0x8689b8b gimplify_function_tree(tree_node*)^M
        ../../src-trunk/gcc/gimplify.c:12949^M
0x84f7690 cgraph_node::analyze()^M
        ../../src-trunk/gcc/cgraphunit.c:667^M
0x84fa1d8 analyze_functions^M
        ../../src-trunk/gcc/cgraphunit.c:1126^M
0x84fadd3 symbol_table::finalize_compilation_unit()^M
        ../../src-trunk/gcc/cgraphunit.c:2833^M
Please submit a full bug report,^M
with preprocessed source if appropriate.^M
Please include the complete backtrace with any bug report.^M
See <https://gcc.gnu.org/bugs/> for instructions.^M
compiler exited with status 1
FAIL: gcc.dg/warn-strlen-no-nul.c (internal compiler error)

on i386.
Bernd Edlinger Nov. 5, 2018, 11:20 p.m. UTC | #6
On 11/5/18 1:28 AM, H.J. Lu wrote:
> On Sun, Nov 4, 2018 at 10:02 AM Jeff Law <law@redhat.com> wrote:
>>
>> On 10/22/18 9:08 AM, Bernd Edlinger wrote:
>>> Hi!
>>>
>>> This makes c_strlen avoid an unsafe strlen folding of const arguments
>>> with non-const offset.  Currently a negative out of bounds offset
>>> makes the strlen function return an extremely large number, and
>>> at the same time, prevents the VRP machinery, to determine the correct
>>> range if the strlen function in this case.
>>>
>>> Fixed by doing the whole computation in size_t and casting the
>>> result back to ssize_t.
>>>
>>>
>>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>>> Is it OK for trunk?
>>>
>>>
>>> Thanks
>>> Bernd.
>>>
>>>
>>> patch-pr86572.diff
>>>
>>> gcc:
>>> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
>>>
>>>        PR tree-optimization/86572
>>>        * builtins.c (c_strlen): Handle negative offsets in a safe way.
>>>
>>> testsuite:
>>> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
>>>
>>>        PR tree-optimization/86572
>>>        * gcc.dg/pr86572.c: New test.
>> OK.
>> jeff
> 
> This caused:
> 
> /export/gnu/import/git/gcc-test-ia32/src-trunk/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c:56:1:
> internal compiler error: verify_gimple failed^M
> 0x8922dc4 verify_gimple_in_seq(gimple*)^M
>          ../../src-trunk/gcc/tree-cfg.c:5082^M
> 0x86899d7 gimplify_body(tree_node*, bool)^M
>          ../../src-trunk/gcc/gimplify.c:12859^M
> 0x8689b8b gimplify_function_tree(tree_node*)^M
>          ../../src-trunk/gcc/gimplify.c:12949^M
> 0x84f7690 cgraph_node::analyze()^M
>          ../../src-trunk/gcc/cgraphunit.c:667^M
> 0x84fa1d8 analyze_functions^M
>          ../../src-trunk/gcc/cgraphunit.c:1126^M
> 0x84fadd3 symbol_table::finalize_compilation_unit()^M
>          ../../src-trunk/gcc/cgraphunit.c:2833^M
> Please submit a full bug report,^M
> with preprocessed source if appropriate.^M
> Please include the complete backtrace with any bug report.^M
> See <https://gcc.gnu.org/bugs/> for instructions.^M
> compiler exited with status 1
> FAIL: gcc.dg/warn-strlen-no-nul.c (internal compiler error)
> 
> on i386.
> 

Ah yes thanks.

This is caused by an incorrect folding in string_constant.
After stripping the type casts in the POINTER_PLUS_EXPR
we add the offset which is sizetype to what is left
over from arg1, which is probably even a correctness issue,
if the type cast was a narrowing one.

Bootstrapped and reg-tested on x86_64-pc-linux-gnu (this time
tested with RUNTESTFLAGS="--target_board=unix\{-m32,\}")
Is it OK for trunk?


Thanks
Bernd.
2018-11-05  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* expr.c (string_constant): Don't strip NOPS in subexpressions.
	Fold PLUS_EXPR correctly.

Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 265778)
+++ gcc/expr.c	(working copy)
@@ -11357,19 +11357,16 @@ string_constant (tree arg, tree *ptr_offset, tree
       tree arg0 = TREE_OPERAND (arg, 0);
       tree arg1 = TREE_OPERAND (arg, 1);
 
-      STRIP_NOPS (arg0);
-      STRIP_NOPS (arg1);
-
-      if (TREE_CODE (arg0) == ADDR_EXPR)
-	;   /* Do nothing.  */
-      else if (TREE_CODE (arg1) == ADDR_EXPR)
-	std::swap (arg0, arg1);
-      else
-	return NULL_TREE;
-
       tree offset;
-      if (tree str = string_constant (arg0, &offset, mem_size, decl))
+      tree str = string_constant (arg0, &offset, mem_size, decl);
+      if (!str)
 	{
+	   str = string_constant (arg1, &offset, mem_size, decl);
+	   arg1 = arg0;
+	}
+
+      if (str)
+	{
 	  /* Avoid pointers to arrays (see bug 86622).  */
 	  if (POINTER_TYPE_P (TREE_TYPE (arg))
 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
@@ -11379,7 +11376,8 @@ string_constant (tree arg, tree *ptr_offset, tree
 		   && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
 	    return NULL_TREE;
 
-	  tree type = TREE_TYPE (arg1);
+	  tree type = TREE_TYPE (offset);
+	  arg1 = fold_convert (type, arg1);
 	  *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
 	  return str;
 	}
@@ -11411,7 +11409,8 @@ string_constant (tree arg, tree *ptr_offset, tree
 	    return NULL_TREE;
 
 	  tree rhs2 = gimple_assign_rhs2 (stmt);
-	  tree type = TREE_TYPE (rhs2);
+	  tree type = TREE_TYPE (offset);
+	  rhs2 = fold_convert (type, rhs2);
 	  *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
 	  return str;
 	}
H.J. Lu Nov. 8, 2018, 1:44 p.m. UTC | #7
On Mon, Nov 5, 2018 at 3:20 PM Bernd Edlinger <bernd.edlinger@hotmail.de> wrote:
>
> On 11/5/18 1:28 AM, H.J. Lu wrote:
> > On Sun, Nov 4, 2018 at 10:02 AM Jeff Law <law@redhat.com> wrote:
> >>
> >> On 10/22/18 9:08 AM, Bernd Edlinger wrote:
> >>> Hi!
> >>>
> >>> This makes c_strlen avoid an unsafe strlen folding of const arguments
> >>> with non-const offset.  Currently a negative out of bounds offset
> >>> makes the strlen function return an extremely large number, and
> >>> at the same time, prevents the VRP machinery, to determine the correct
> >>> range if the strlen function in this case.
> >>>
> >>> Fixed by doing the whole computation in size_t and casting the
> >>> result back to ssize_t.
> >>>
> >>>
> >>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> >>> Is it OK for trunk?
> >>>
> >>>
> >>> Thanks
> >>> Bernd.
> >>>
> >>>
> >>> patch-pr86572.diff
> >>>
> >>> gcc:
> >>> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> >>>
> >>>        PR tree-optimization/86572
> >>>        * builtins.c (c_strlen): Handle negative offsets in a safe way.
> >>>
> >>> testsuite:
> >>> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> >>>
> >>>        PR tree-optimization/86572
> >>>        * gcc.dg/pr86572.c: New test.
> >> OK.
> >> jeff
> >
> > This caused:
> >
> > /export/gnu/import/git/gcc-test-ia32/src-trunk/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c:56:1:
> > internal compiler error: verify_gimple failed^M
> > 0x8922dc4 verify_gimple_in_seq(gimple*)^M
> >          ../../src-trunk/gcc/tree-cfg.c:5082^M
> > 0x86899d7 gimplify_body(tree_node*, bool)^M
> >          ../../src-trunk/gcc/gimplify.c:12859^M
> > 0x8689b8b gimplify_function_tree(tree_node*)^M
> >          ../../src-trunk/gcc/gimplify.c:12949^M
> > 0x84f7690 cgraph_node::analyze()^M
> >          ../../src-trunk/gcc/cgraphunit.c:667^M
> > 0x84fa1d8 analyze_functions^M
> >          ../../src-trunk/gcc/cgraphunit.c:1126^M
> > 0x84fadd3 symbol_table::finalize_compilation_unit()^M
> >          ../../src-trunk/gcc/cgraphunit.c:2833^M
> > Please submit a full bug report,^M
> > with preprocessed source if appropriate.^M
> > Please include the complete backtrace with any bug report.^M
> > See <https://gcc.gnu.org/bugs/> for instructions.^M
> > compiler exited with status 1
> > FAIL: gcc.dg/warn-strlen-no-nul.c (internal compiler error)
> >
> > on i386.
> >
>
> Ah yes thanks.
>
> This is caused by an incorrect folding in string_constant.
> After stripping the type casts in the POINTER_PLUS_EXPR
> we add the offset which is sizetype to what is left
> over from arg1, which is probably even a correctness issue,
> if the type cast was a narrowing one.
>
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu (this time
> tested with RUNTESTFLAGS="--target_board=unix\{-m32,\}")
> Is it OK for trunk?
>

I opened:

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

to track it.
Jeff Law Nov. 9, 2018, 8:01 p.m. UTC | #8
On 11/5/18 4:20 PM, Bernd Edlinger wrote:
> On 11/5/18 1:28 AM, H.J. Lu wrote:
>> On Sun, Nov 4, 2018 at 10:02 AM Jeff Law <law@redhat.com> wrote:
>>> On 10/22/18 9:08 AM, Bernd Edlinger wrote:
>>>> Hi!
>>>>
>>>> This makes c_strlen avoid an unsafe strlen folding of const arguments
>>>> with non-const offset.  Currently a negative out of bounds offset
>>>> makes the strlen function return an extremely large number, and
>>>> at the same time, prevents the VRP machinery, to determine the correct
>>>> range if the strlen function in this case.
>>>>
>>>> Fixed by doing the whole computation in size_t and casting the
>>>> result back to ssize_t.
>>>>
>>>>
>>>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>>>> Is it OK for trunk?
>>>>
>>>>
>>>> Thanks
>>>> Bernd.
>>>>
>>>>
>>>> patch-pr86572.diff
>>>>
>>>> gcc:
>>>> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
>>>>
>>>>        PR tree-optimization/86572
>>>>        * builtins.c (c_strlen): Handle negative offsets in a safe way.
>>>>
>>>> testsuite:
>>>> 2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>
>>>>
>>>>        PR tree-optimization/86572
>>>>        * gcc.dg/pr86572.c: New test.
>>> OK.
>>> jeff
>> This caused:
>>
>> /export/gnu/import/git/gcc-test-ia32/src-trunk/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c:56:1:
>> internal compiler error: verify_gimple failed^M
>> 0x8922dc4 verify_gimple_in_seq(gimple*)^M
>>          ../../src-trunk/gcc/tree-cfg.c:5082^M
>> 0x86899d7 gimplify_body(tree_node*, bool)^M
>>          ../../src-trunk/gcc/gimplify.c:12859^M
>> 0x8689b8b gimplify_function_tree(tree_node*)^M
>>          ../../src-trunk/gcc/gimplify.c:12949^M
>> 0x84f7690 cgraph_node::analyze()^M
>>          ../../src-trunk/gcc/cgraphunit.c:667^M
>> 0x84fa1d8 analyze_functions^M
>>          ../../src-trunk/gcc/cgraphunit.c:1126^M
>> 0x84fadd3 symbol_table::finalize_compilation_unit()^M
>>          ../../src-trunk/gcc/cgraphunit.c:2833^M
>> Please submit a full bug report,^M
>> with preprocessed source if appropriate.^M
>> Please include the complete backtrace with any bug report.^M
>> See <https://gcc.gnu.org/bugs/> for instructions.^M
>> compiler exited with status 1
>> FAIL: gcc.dg/warn-strlen-no-nul.c (internal compiler error)
>>
>> on i386.
>>
> Ah yes thanks.
> 
> This is caused by an incorrect folding in string_constant.
> After stripping the type casts in the POINTER_PLUS_EXPR
> we add the offset which is sizetype to what is left
> over from arg1, which is probably even a correctness issue,
> if the type cast was a narrowing one.
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu (this time
> tested with RUNTESTFLAGS="--target_board=unix\{-m32,\}")
> Is it OK for trunk?
> 
> 
> Thanks
> Bernd.
> 
> 
> 
> patch-fix-string-cst.diff
> 
> 2018-11-05  Bernd Edlinger  <bernd.edlinger@hotmail.de>
> 
> 	* expr.c (string_constant): Don't strip NOPS in subexpressions.
> 	Fold PLUS_EXPR correctly.
OK.
jeff
diff mbox series

Patch

gcc:
2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR tree-optimization/86572
	* builtins.c (c_strlen): Handle negative offsets in a safe way.

testsuite:
2018-10-22  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	PR tree-optimization/86572
	* gcc.dg/pr86572.c: New test.

diff -Npur gcc/builtins.c gcc/builtins.c
--- gcc/builtins.c	2018-10-21 10:41:08.000000000 +0200
+++ gcc/builtins.c	2018-10-22 10:45:25.846236006 +0200
@@ -734,11 +734,14 @@  c_strlen (tree src, int only_value, c_st
 	 of the string subtract the offset from the length of the string,
 	 and return that.  Otherwise the length is zero.  Take care to
 	 use SAVE_EXPR in case the OFFSET has side-effects.  */
-      tree offsave = TREE_SIDE_EFFECTS (byteoff) ? save_expr (byteoff) : byteoff;
-      offsave = fold_convert (ssizetype, offsave);
+      tree offsave = TREE_SIDE_EFFECTS (byteoff) ? save_expr (byteoff)
+						 : byteoff;
+      offsave = fold_convert_loc (loc, sizetype, offsave);
       tree condexp = fold_build2_loc (loc, LE_EXPR, boolean_type_node, offsave,
-				      build_int_cst (ssizetype, len));
-      tree lenexp = size_diffop_loc (loc, ssize_int (len), offsave);
+				      size_int (len));
+      tree lenexp = fold_build2_loc (loc, MINUS_EXPR, sizetype, size_int (len),
+				     offsave);
+      lenexp = fold_convert_loc (loc, ssizetype, lenexp);
       return fold_build3_loc (loc, COND_EXPR, ssizetype, condexp, lenexp,
 			      build_zero_cst (ssizetype));
     }
diff -Npur gcc/testsuite/gcc.dg/pr86572.c gcc/testsuite/gcc.dg/pr86572.c
--- gcc/testsuite/gcc.dg/pr86572.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr86572.c	2018-10-22 12:35:25.771640418 +0200
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+const char buf[40] = "test";
+void test (int x)
+{
+  if (__builtin_strlen (buf + x) > 4)
+    __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */