So this is the infrastructure changes necessary to enable Martin's patch
to detect strings without NUL termination passed to the sprintf
routines.  There's three tightly related changes.

First in get_range_strlen, we verify that c_strlen found an unterminated
string before setting *nonstr.

Second, also in get_range_strlen, in the event we encounter an
unterminated string, we still want to bubble up the min/max lengths.
The sprintf code will check those against the directive's specified
length.   If the length specified by the sprintf directive ensures we
won't walk off the end of the string, then the warning is suppressed.

Bubbling those lengths up caused heartburn for the strlen folding bits
which blindly looked at the returned min/max without first verifying
that the string was properly terminated.  So the 3rd hunk disables
strlen folding when get_range_strlen indicates the string was not
properly terminated.



Bootstrapped and regression tested both in isolation and with Martin's
patch to warn for unterminated strings used in sprintf calls.

Installing on the trunk.  I'll be installing Martin's patch momentarily
as well.


Jeff
commit 89d3e5cf174b6555ba76eb4bef49555fe00fc5b6
Author: Jeff Law <l...@torsion.usersys.redhat.com>
Date:   Wed Oct 3 12:02:12 2018 -0400

            * gimple-fold.c (get_range_strlen): Only set *nonstr when
            an unterminated string is discovered.  Bubble up range
            even for unterminated strings.
            (gimple_fold_builtin_strlen): Do not fold if get_range_strlen
            indicates the string was not terminated via NONSTR.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6acb077b357..aa10aa07269 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,12 @@
-2018-10-3  Aldy Hernandez  <al...@redhat.com>
+2018-10-02  Jeff Law  <l...@redhat.com>
+
+       * gimple-fold.c (get_range_strlen): Only set *nonstr when
+       an unterminated string is discovered.  Bubble up range
+       even for unterminated strings.
+       (gimple_fold_builtin_strlen): Do not fold if get_range_strlen
+       indicates the string was not terminated via NONSTR.
+
+2018-10-03  Aldy Hernandez  <al...@redhat.com>
 
        * tree-vrp.c (extract_range_from_unary_expr): Special case all
        pointer conversions.
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fa1fc60876c..fe6bc08bdd9 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1344,8 +1344,13 @@ get_range_strlen (tree arg, tree length[2], bitmap 
*visited, int type,
 
          /* If we potentially had a non-terminated string, then
             bubble that information up to the caller.  */
-         if (!val)
-           *nonstr = data.decl;
+         if (!val && data.decl)
+           {
+             *nonstr = data.decl;
+             *minlen = data.len;
+             *maxlen = data.len;
+             return type == 0 ? false : true;
+           }
        }
 
       if (!val && fuzzy)
@@ -3596,6 +3601,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
   tree nonstr;
   tree lenrange[2];
   if (!get_range_strlen (arg, lenrange, 1, true, &nonstr)
+      && !nonstr
       && lenrange[0] && TREE_CODE (lenrange[0]) == INTEGER_CST
       && lenrange[1] && TREE_CODE (lenrange[1]) == INTEGER_CST)
     {

Reply via email to