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.
gcc: 2018-10-22 Bernd Edlinger <bernd.edlin...@hotmail.de> PR tree-optimization/86572 * builtins.c (c_strlen): Handle negative offsets in a safe way. testsuite: 2018-10-22 Bernd Edlinger <bernd.edlin...@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" } } */