On 11/5/18 1:28 AM, H.J. Lu wrote: > On Sun, Nov 4, 2018 at 10:02 AM Jeff Law <l...@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.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. >> 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.edlin...@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; }