]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-ssa-strlen.c
PR middle-end/85602 - -Wsizeof-pointer-memaccess for strncat with size of source
[thirdparty/gcc.git] / gcc / tree-ssa-strlen.c
index 693d9d3491a273a3fb9517e167579b65fcaae640..92545b9ce4d03af5d3fbe296b38b587048476291 100644 (file)
@@ -1757,7 +1757,7 @@ handle_builtin_strncat (built_in_function bcode, gimple_stmt_iterator *gsi)
    assumed to be the argument in some call to strlen() whose relationship
    to SRC is being ascertained.  */
 
-static bool
+bool
 is_strlen_related_p (tree src, tree len)
 {
   if (TREE_CODE (TREE_TYPE (len)) == POINTER_TYPE
@@ -1794,12 +1794,20 @@ is_strlen_related_p (tree src, tree len)
          && (code == BIT_AND_EXPR
              || code == NOP_EXPR)))
     {
-      /* Pointer plus (an integer) and integer cast or truncation are
-        considered among the (potentially) related expressions to strlen.
-        Others are not.  */
+      /* Pointer plus (an integer), and truncation are considered among
+        the (potentially) related expressions to strlen.  */
       return is_strlen_related_p (src, rhs1);
     }
 
+  if (tree rhs2 = gimple_assign_rhs2 (def_stmt))
+    {
+      /* Integer subtraction is considered strlen-related when both
+        arguments are integers and second one is strlen-related.  */
+      rhstype = TREE_TYPE (rhs2);
+      if (INTEGRAL_TYPE_P (rhstype) && code == MINUS_EXPR)
+       return is_strlen_related_p (src, rhs2);
+    }
+
   return false;
 }
 
@@ -1870,9 +1878,22 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
   if (TREE_CODE (dstdecl) == ADDR_EXPR)
     dstdecl = TREE_OPERAND (dstdecl, 0);
 
-  /* If the destination refers to a an array/pointer declared nonstring
-     return early.  */
   tree ref = NULL_TREE;
+
+  if (!sidx)
+    {
+      /* If the source is a non-string return early to avoid warning
+        for possible truncation (if the truncation is certain SIDX
+        is non-zero).  */
+      tree srcdecl = gimple_call_arg (stmt, 1);
+      if (TREE_CODE (srcdecl) == ADDR_EXPR)
+       srcdecl = TREE_OPERAND (srcdecl, 0);
+      if (get_attr_nonstring_decl (srcdecl, &ref))
+       return false;
+    }
+
+  /* Likewise, if the destination refers to a an array/pointer declared
+     nonstring return early.  */
   if (get_attr_nonstring_decl (dstdecl, &ref))
     return false;