Hi!

This patch adds some more checks to c_getstr to fix PR middle-end/87053
wrong code bug.

Unfortunately this patch alone is not sufficient to fix the problem,
but also the patch for PR 86714 that hardens c_getstr is necessary
to prevent the wrong folding.


Bootstrapped and reg-tested on top of my PR 86711/86714 patch.
Is it OK for trunk?


Thanks
Bernd.


gcc:
2018-08-22  Bernd Edlinger  <bernd.edlin...@hotmail.de>

	PR middle-end/87053
	* builtins.c (c_strlen): Improve range checks.

testsuite:
2018-08-22  Bernd Edlinger  <bernd.edlin...@hotmail.de>

	PR middle-end/87053
	* gcc.c-torture/execute/pr87053.c: New test.

diff -Npur gcc/builtins.c gcc/builtins.c
--- gcc/builtins.c	2018-08-17 05:02:16.000000000 +0200
+++ gcc/builtins.c	2018-08-22 08:51:21.287960030 +0200
@@ -576,7 +576,7 @@ string_length (const void *ptr, unsigned
 tree
 c_strlen (tree src, int only_value, unsigned eltsize)
 {
-  gcc_assert (eltsize == 1 || eltsize == 2 || eltsize == 4);
+  gcc_checking_assert (eltsize == 1 || eltsize == 2 || eltsize == 4);
   STRIP_NOPS (src);
   if (TREE_CODE (src) == COND_EXPR
       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
@@ -665,10 +665,10 @@ c_strlen (tree src, int only_value, unsi
      a null character if we can represent it as a single HOST_WIDE_INT.  */
   if (byteoff == 0)
     eltoff = 0;
-  else if (! tree_fits_shwi_p (byteoff))
+  else if (! tree_fits_uhwi_p (byteoff) || tree_to_uhwi (byteoff) % eltsize)
     eltoff = -1;
   else
-    eltoff = tree_to_shwi (byteoff) / eltsize;
+    eltoff = tree_to_uhwi (byteoff) / eltsize;
 
   /* If the offset is known to be out of bounds, warn, and call strlen at
      runtime.  */
@@ -700,6 +700,10 @@ c_strlen (tree src, int only_value, unsi
   unsigned len = string_length (ptr + eltoff * eltsize, eltsize,
 				strelts - eltoff);
 
+  /* Don't know what to return if there was no zero termination.  */
+  if (len > maxelts - eltoff)
+    return NULL_TREE;
+
   return ssize_int (len);
 }
 
diff -Npur gcc/testsuite/gcc.c-torture/execute/pr87053.c gcc/testsuite/gcc.c-torture/execute/pr87053.c
--- gcc/testsuite/gcc.c-torture/execute/pr87053.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr87053.c	2018-08-22 12:54:00.801019240 +0200
@@ -0,0 +1,17 @@
+/* PR middle-end/87053 */
+
+const union
+{ struct {
+    char x[4];
+    char y[4];
+  };
+  struct {
+    char z[8];
+  };
+} u = {{"1234", "567"}};
+
+int main ()
+{
+  if (__builtin_strlen (u.z) != 7)
+    __builtin_abort ();
+}

Reply via email to