https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86400

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
             Status|NEW                         |ASSIGNED
             Blocks|                            |83819
           Assignee|unassigned at gcc dot gnu.org      |msebor at gcc dot 
gnu.org

--- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> ---
Confirmed.  The strlen pass sees:

  static char root[1][2] = {"/"};
  ...
  _1 = __builtin_strlen (&root);


but the code in maybe_set_strlen_range() assumes the argument has the correct
type (i.e., char*, not char[][2]) and uses TYPE_DOMAIN to determine the upper
bound of the array which returns the bound of the outer array in this case. 
Using TYPE_SIZE instead avoids the problem:

Index: gcc/tree-ssa-strlen.c
===================================================================
--- gcc/tree-ssa-strlen.c       (revision 262418)
+++ gcc/tree-ssa-strlen.c       (working copy)
@@ -1156,22 +1156,17 @@ maybe_set_strlen_range (tree lhs, tree src, tree b
       if (src_is_array && !array_at_struct_end_p (src))
        {
          tree type = TREE_TYPE (src);
-         if (tree dom = TYPE_DOMAIN (type))
-           {
-             tree maxval = TYPE_MAX_VALUE (dom);
-             if (maxval)
-               max = wi::to_wide (maxval);
-             else
-               max = wi::zero (min.get_precision ());
+         if (tree size = TYPE_SIZE_UNIT (type))
+           if (size && TREE_CODE (size) == INTEGER_CST)
+             max = wi::to_wide (size);

-             /* For strlen() the upper bound above is equal to
-                the longest string that can be stored in the array
-                (i.e., it accounts for the terminating nul.  For
-                strnlen() bump up the maximum by one since the array
-                need not be nul-terminated.  */
-             if (bound)
-               ++max;
-           }
+         /* For strlen() the upper bound above is equal to
+            the longest string that can be stored in the array
+            (i.e., it accounts for the terminating nul.  For
+            strnlen() bump up the maximum by one since the array
+            need not be nul-terminated.  */
+         if (!bound && max != 0)
+           --max;
        }
       else
        {


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83819
[Bug 83819] [meta-bug] missing strlen optimizations

Reply via email to