builtins.c (compute_objsize): Add an argument.
authorMartin Sebor <msebor@redhat.com>
Fri, 4 Oct 2019 21:26:27 +0000 (21:26 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Fri, 4 Oct 2019 21:26:27 +0000 (15:26 -0600)
gcc/ChangeLog:

* builtins.c (compute_objsize): Add an argument.
* tree-object-size.c (addr_object_size): Same.
(compute_builtin_object_size): Same.
* tree-object-size.h (compute_builtin_object): Same.

gcc/testsuite/ChangeLog:

* gcc.dg/Wstringop-overflow-17.c: New test.

From-SVN: r276602

gcc/ChangeLog
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wstringop-overflow-17.c [new file with mode: 0644]
gcc/tree-object-size.c
gcc/tree-object-size.h

index 3c964970046d5e1622b20d1bd3c52d4acbe347d3..6a1c17c0465a06859af415187b84605bb160c73c 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-04  Martin Sebor  <msebor@redhat.com>
+
+       * builtins.c (compute_objsize): Add an argument.
+       * tree-object-size.c (addr_object_size): Same.
+       (compute_builtin_object_size): Same.
+       * tree-object-size.h (compute_builtin_object): Same.
+
 2019-10-04  Jan Hubicka  <hubicka@ucw.cz>
 
        * ipa-inline.c (inline_insns_single, inline_insns_auto): Fix typo.
index fa17afd2e8a974338adbbeb583e42124dd973f3a..a1dc83c0b2493d1559862e75f41ed33316deecb6 100644 (file)
@@ -3587,7 +3587,7 @@ compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */)
   /* Only the two least significant bits are meaningful.  */
   ostype &= 3;
 
-  if (compute_builtin_object_size (dest, ostype, &size))
+  if (compute_builtin_object_size (dest, ostype, &size, pdecl))
     return build_int_cst (sizetype, size);
 
   if (TREE_CODE (dest) == SSA_NAME)
index f9eefadf22baa6f06b936acfdf50a584ccd5f0e3..9a5adf787dd4ebf9014fff2c6251f9121f376832 100644 (file)
@@ -1,3 +1,7 @@
+2019-10-04  Martin Sebor  <msebor@redhat.com>
+
+       * gcc.dg/Wstringop-overflow-17.c: New test.
+
 2019-10-04  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran.91959
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
new file mode 100644 (file)
index 0000000..de22c98
--- /dev/null
@@ -0,0 +1,20 @@
+/* Test to verify that -Wstringop-overflow mentions the referenced object
+   i.
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+static void copy_n (char *d, const char *s, int n)
+{
+  while (n--)
+    *d++ = *s++;
+  *d = 0;           // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+void sink (void*);
+
+void call_copy_n (const char *s)
+{
+  char a[3];        // { dg-message "destination object declared here" }
+  copy_n (a, "1234567", 7);
+  sink (a);
+}
index f9ad7e83943e30925685ed2916d6c3b91f3bdc60..db9b5694e85d2afce4df21e730823efd3dfc5f7e 100644 (file)
@@ -54,7 +54,8 @@ static const unsigned HOST_WIDE_INT unknown[4] = {
 
 static tree compute_object_offset (const_tree, const_tree);
 static bool addr_object_size (struct object_size_info *,
-                             const_tree, int, unsigned HOST_WIDE_INT *);
+                             const_tree, int, unsigned HOST_WIDE_INT *,
+                             tree * = NULL);
 static unsigned HOST_WIDE_INT alloc_object_size (const gcall *, int);
 static tree pass_through_call (const gcall *);
 static void collect_object_sizes_for (struct object_size_info *, tree);
@@ -172,10 +173,15 @@ compute_object_offset (const_tree expr, const_tree var)
 
 static bool
 addr_object_size (struct object_size_info *osi, const_tree ptr,
-                 int object_size_type, unsigned HOST_WIDE_INT *psize)
+                 int object_size_type, unsigned HOST_WIDE_INT *psize,
+                 tree *pdecl /* = NULL */)
 {
   tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
 
+  tree dummy;
+  if (!pdecl)
+    pdecl = &dummy;
+
   gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
 
   /* Set to unknown and overwrite just before returning if the size
@@ -195,7 +201,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
          || TREE_CODE (TREE_OPERAND (pt_var, 0)) != SSA_NAME)
        {
          compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
-                                      object_size_type & ~1, &sz);
+                                      object_size_type & ~1, &sz, pdecl);
        }
       else
        {
@@ -232,7 +238,10 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
           && DECL_P (pt_var)
           && tree_fits_uhwi_p (DECL_SIZE_UNIT (pt_var))
           && tree_to_uhwi (DECL_SIZE_UNIT (pt_var)) < offset_limit)
-    pt_var_size = DECL_SIZE_UNIT (pt_var);
+    {
+      *pdecl = pt_var;
+      pt_var_size = DECL_SIZE_UNIT (pt_var);
+    }
   else if (pt_var
           && TREE_CODE (pt_var) == STRING_CST
           && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
@@ -478,13 +487,16 @@ pass_through_call (const gcall *call)
 
 
 /* Compute __builtin_object_size value for PTR and set *PSIZE to
-   the resulting value.  OBJECT_SIZE_TYPE is the second argument
-   to __builtin_object_size.  Return true on success and false
-   when the object size could not be determined.  */
+   the resulting value.  If the declared object is known and PDECL
+   is nonnull, sets *PDECL to the object's DECL.  OBJECT_SIZE_TYPE
+   is the second argument   to __builtin_object_size.
+   Returns true on success and false when the object size could not
+   be determined.  */
 
 bool
 compute_builtin_object_size (tree ptr, int object_size_type,
-                            unsigned HOST_WIDE_INT *psize)
+                            unsigned HOST_WIDE_INT *psize,
+                            tree *pdecl /* = NULL */)
 {
   gcc_assert (object_size_type >= 0 && object_size_type <= 3);
 
@@ -496,7 +508,7 @@ compute_builtin_object_size (tree ptr, int object_size_type,
     init_offset_limit ();
 
   if (TREE_CODE (ptr) == ADDR_EXPR)
-    return addr_object_size (NULL, ptr, object_size_type, psize);
+    return addr_object_size (NULL, ptr, object_size_type, psize, pdecl);
 
   if (TREE_CODE (ptr) != SSA_NAME
       || !POINTER_TYPE_P (TREE_TYPE (ptr)))
@@ -520,7 +532,8 @@ compute_builtin_object_size (tree ptr, int object_size_type,
              ptr = gimple_assign_rhs1 (def);
 
              if (tree_fits_shwi_p (offset)
-                 && compute_builtin_object_size (ptr, object_size_type, psize))
+                 && compute_builtin_object_size (ptr, object_size_type,
+                                                 psize, pdecl))
                {
                  /* Return zero when the offset is out of bounds.  */
                  unsigned HOST_WIDE_INT off = tree_to_shwi (offset);
index 420af3e0633b6598222743e692dea489649f80c8..65528b3a696fac3cd567c80163597b6d2442d4d5 100644 (file)
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 extern void init_object_sizes (void);
 extern void fini_object_sizes (void);
-extern bool compute_builtin_object_size (tree, int, unsigned HOST_WIDE_INT *);
+extern bool compute_builtin_object_size (tree, int, unsigned HOST_WIDE_INT *,
+                                        tree * = NULL);
 
 #endif  // GCC_TREE_OBJECT_SIZE_H