This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] mention referenced object in more -Wstringop-overflow instances


The attached patch adds an optional argument to
compute_builtin_object_size to let it return the DECL of the object
whose size it's called to compute.  This lets -Wstringop-overflow
point to the object in more instances of the warning than it does
now (but by no means all of them -- more work is needed to make
that happen).  This can be helpful when the object is declared in
a different function than the access.

Tested on x86_64-linux.

Martin

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.

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 276472)
+++ gcc/builtins.c	(working copy)
@@ -3587,7 +3587,7 @@ compute_objsize (tree dest, int ostype, tree *pdec
   /* 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: gcc/tree-object-size.h
===================================================================
--- gcc/tree-object-size.h	(revision 276472)
+++ gcc/tree-object-size.h	(working copy)
@@ -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
Index: gcc/tree-object-size.c
===================================================================
--- gcc/tree-object-size.c	(revision 276491)
+++ gcc/tree-object-size.c	(working copy)
@@ -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
 
 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, co
 	  || 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, co
 	   && 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_
     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_
 	      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: gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
===================================================================
--- gcc/testsuite/gcc.dg/Wstringop-overflow-17.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/Wstringop-overflow-17.c	(working copy)
@@ -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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]