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;
 	}


Reply via email to