On 9/16/18 1:58 PM, Bernd Edlinger wrote:
> Hi,
> 
> this is a cleanup of the recently added strlen/strcpy/stpcpy
> no nul warning code.
> 
> Most importantly it moves the SSA_NAME handling from
> unterminated_array to string_constant, thereby fixing
> another round of xfails in the strlen and stpcpy test cases.
> 
> I need to say that the fix for bug 86622 is relying in
> type info on the pointer which is probably not safe in
> GIMPLE in the light of the recent discussion.
> 
> I had to add two further exceptions, which should
> be safe in general: that is a pointer arithmentic on a string
> literal is okay, and arithmetic on a string constant
> that is exactly the size of the whole DECL, cannot
> access an adjacent member.
> 
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?
> 
> 
> Thanks
> Bernd.
> 
> 
> patch-cleanup-no-nul.diff
> 
> gcc:
> 2018-09-16  Bernd Edlinger  <bernd.edlin...@hotmail.de>
> 
>       * builtins.h (unterminated_array): Remove prototype.
>         * builtins.c (unterminated_array): Simplify.  Make static.
>         (expand_builtin_strcpy_args): Don't use TREE_NO_WARNING here.
>       (expand_builtin_stpcpy_1): Remove warn_string_no_nul without effect.
>       * expr.c (string_constant): Handle SSA_NAME.  Add more exceptions
>       where pointer arithmetic is safe.
>       * gimple-fold.c (get_range_strlen): Handle nonstr like in c_strlen.
>       (get_max_strlen): Remove the unnecessary mynonstr handling.
>       (gimple_fold_builtin_strcpy): Simplify.
>       (gimple_fold_builtin_stpcpy): Simplify.
>       (gimple_fold_builtin_sprintf): Remove NO_WARNING propagation
>       without effect.
>       (gimple_fold_builtin_strlen): Simplify.
> 
> testsuite:
> 2018-09-16  Bernd Edlinger  <bernd.edlin...@hotmail.de>
> 
>       * gcc.dg/warn-stpcpy-no-nul.c: Remove xfails.
>       * gcc.dg/warn-strlen-no-nul.c: Remove xfails.
I extracted the unterminated_array simplifications and the changes to
string_constant and committed them to the trunk.

I left unterminated_array with external scope as a patch from Martin
wants to call it from outside builtins.c.

jeff
commit c1451dd20f9064084df7b45c4635c1bcb57a712d
Author: Jeff Law <l...@torsion.usersys.redhat.com>
Date:   Mon Sep 17 14:09:55 2018 -0400

            PR c/87387
            * builtins.c (unterminated_array): Simplify.
            * expr.c (string_constant): Handle SSA_NAME.  Add more exceptions
            where pointer arithmetic is safe.
    
            * gcc.dg/warn-stpcpy-no-nul.c: Drop unnecessary xfails.
            * gcc.dg/warn-stplen-no-nul.c: Likewise.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6be143e9f18..8ff607e4d23 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-25  Bernd Edlinger  <bernd.edlin...@hotmail.de>
+
+       PR c/87387
+        * builtins.c (unterminated_array): Simplify.
+       * expr.c (string_constant): Handle SSA_NAME.  Add more exceptions
+       where pointer arithmetic is safe.
+
 2018-09-25  Richard Biener  <rguent...@suse.de>
 
        PR debug/83941
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1d4de099726..5f00208ff09 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -570,28 +570,9 @@ warn_string_no_nul (location_t loc, const char *fn, tree 
arg, tree decl)
 tree
 unterminated_array (tree exp)
 {
-  if (TREE_CODE (exp) == SSA_NAME)
-    {
-      gimple *stmt = SSA_NAME_DEF_STMT (exp);
-      if (!is_gimple_assign (stmt))
-       return NULL_TREE;
-
-      tree rhs1 = gimple_assign_rhs1 (stmt);
-      tree_code code = gimple_assign_rhs_code (stmt);
-      if (code == ADDR_EXPR
-         && TREE_CODE (TREE_OPERAND (rhs1, 0)) == ARRAY_REF)
-       rhs1 = rhs1;
-      else if (code != POINTER_PLUS_EXPR)
-       return NULL_TREE;
-
-      exp = rhs1;
-    }
-
   tree nonstr = NULL;
-  if (c_strlen (exp, 1, &nonstr, 1) == NULL && nonstr)
-    return nonstr;
-
-  return NULL_TREE;
+  c_strlen (exp, 1, &nonstr);
+  return nonstr;
 }
 
 /* Compute the length of a null-terminated character string or wide
diff --git a/gcc/expr.c b/gcc/expr.c
index b8782b9b133..583c7f008ff 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11372,7 +11372,10 @@ string_constant (tree arg, tree *ptr_offset, tree 
*mem_size, tree *decl)
          /* Avoid pointers to arrays (see bug 86622).  */
          if (POINTER_TYPE_P (TREE_TYPE (arg))
              && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
-             && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF)
+             && !(decl && !*decl)
+             && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
+                  && mem_size && tree_fits_uhwi_p (*mem_size)
+                  && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
            return NULL_TREE;
 
          tree type = TREE_TYPE (arg1);
@@ -11381,6 +11384,38 @@ string_constant (tree arg, tree *ptr_offset, tree 
*mem_size, tree *decl)
        }
       return NULL_TREE;
     }
+  else if (TREE_CODE (arg) == SSA_NAME)
+    {
+      gimple *stmt = SSA_NAME_DEF_STMT (arg);
+      if (!is_gimple_assign (stmt))
+       return NULL_TREE;
+
+      tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree_code code = gimple_assign_rhs_code (stmt);
+      if (code == ADDR_EXPR)
+       return string_constant (rhs1, ptr_offset, mem_size, decl);
+      else if (code != POINTER_PLUS_EXPR)
+       return NULL_TREE;
+
+      tree offset;
+      if (tree str = string_constant (rhs1, &offset, mem_size, decl))
+       {
+         /* Avoid pointers to arrays (see bug 86622).  */
+         if (POINTER_TYPE_P (TREE_TYPE (rhs1))
+             && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
+             && !(decl && !*decl)
+             && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
+                  && mem_size && tree_fits_uhwi_p (*mem_size)
+                  && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
+           return NULL_TREE;
+
+         tree rhs2 = gimple_assign_rhs2 (stmt);
+         tree type = TREE_TYPE (rhs2);
+         *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
+         return str;
+       }
+      return NULL_TREE;
+    }
   else if (DECL_P (arg))
     array = arg;
   else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 05dbb0d40ea..7b26b894b15 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-25  Jeff Law  <l...@redhat.com>
+
+       * gcc.dg/warn-stpcpy-no-nul.c: Drop unnecessary xfails.
+       * gcc.dg/warn-stplen-no-nul.c: Likewise.
+
 2018-09-25  Alexandre Oliva <ol...@adacore.com>
 
        * gnat.dg/dinst.adb: Adjust for locviews.
diff --git a/gcc/testsuite/gcc.dg/warn-stpcpy-no-nul.c 
b/gcc/testsuite/gcc.dg/warn-stpcpy-no-nul.c
index 78c4a7f9286..e718010ec2a 100644
--- a/gcc/testsuite/gcc.dg/warn-stpcpy-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-stpcpy-no-nul.c
@@ -71,13 +71,13 @@ void test_two_dim_array (char *d)
   T (&b[3][1] + 1);     /* { dg-warning "nul" }  */
   T (&b[3][v0]);        /* { dg-warning "nul" }  */
   T (&b[3][1] + v0);    /* { dg-warning "nul" }  */
-  T (&b[3][v0] + v1);   /* { dg-warning "nul" "bug ???" { xfail *-*-* } }  */
+  T (&b[3][v0] + v1);   /* { dg-warning "nul" }  */
 
   T (&b[i3][i1]);       /* { dg-warning "nul" }  */
   T (&b[i3][i1] + i1);  /* { dg-warning "nul" }  */
   T (&b[i3][v0]);       /* { dg-warning "nul" }  */
   T (&b[i3][i1] + v0);  /* { dg-warning "nul" }  */
-  T (&b[i3][v0] + v1);  /* { dg-warning "nul" "bug ???" { xfail *-*-* } }  */
+  T (&b[i3][v0] + v1);  /* { dg-warning "nul" }  */
 
   T (v0 ? "" : b[0]);
   T (v0 ? "" : b[1]);
diff --git a/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c 
b/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c
index 997dfc3540f..b716aa44770 100644
--- a/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strlen-no-nul.c
@@ -71,9 +71,9 @@ T (&b[3][v0] + v1);     /* { dg-warning "nul" }  */
 T (&b[i3][i1]);         /* { dg-warning "nul" }  */
 T (&b[i3][i1] + 1);     /* { dg-warning "nul" }  */
 T (&b[i3][i1] + i1);    /* { dg-warning "nul" }  */
-T (&b[i3][v0]);         /* { dg-warning "nul" "pr86919" { xfail *-*-* } }  */
-T (&b[i3][i1] + v0);    /* { dg-warning "nul" "pr86919" { xfail *-*-* } }  */
-T (&b[i3][v0] + v1);    /* { dg-warning "nul" "pr86919" { xfail *-*-* } }  */
+T (&b[i3][v0]);         /* { dg-warning "nul" }  */
+T (&b[i3][i1] + v0);    /* { dg-warning "nul" }  */
+T (&b[i3][v0] + v1);    /* { dg-warning "nul" }  */
 
 T (v0 ? "" : b[0]);
 T (v0 ? "" : b[1]);
@@ -152,10 +152,10 @@ T (&s.b[1] + v0);     /* { dg-warning "nul" }  */
 
 T (&s.b[i0]);         /* { dg-warning "nul" }  */
 T (&s.b[i0] + i1);    /* { dg-warning "nul" }  */
-T (&s.b[i0] + v0);    /* { dg-warning "nul" "pr86919" { xfail *-*-* } }  */
+T (&s.b[i0] + v0);    /* { dg-warning "nul" }  */
 T (&s.b[i1]);         /* { dg-warning "nul" }  */
 T (&s.b[i1] + i1);    /* { dg-warning "nul" }  */
-T (&s.b[i1] + v0);    /* { dg-warning "nul" "pr86919" { xfail *-*-* } }  */
+T (&s.b[i1] + v0);    /* { dg-warning "nul" }  */
 
 struct B { struct A a[2]; };
 

Reply via email to