aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-10-04 21:26:27 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-10-04 15:26:27 -0600
commit28a5fa54aa47877b6d254430adbf3ca0377beeaa (patch)
treedd44779d5912a216f85020529e623bb2e8acf025
parent0e8879cb36eca17e7b1ff8f2124bbc5ec3c6dc91 (diff)
downloadgcc-28a5fa54aa47877b6d254430adbf3ca0377beeaa.zip
gcc-28a5fa54aa47877b6d254430adbf3ca0377beeaa.tar.gz
gcc-28a5fa54aa47877b6d254430adbf3ca0377beeaa.tar.bz2
builtins.c (compute_objsize): Add an argument.
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/builtins.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-17.c20
-rw-r--r--gcc/tree-object-size.c33
-rw-r--r--gcc/tree-object-size.h3
6 files changed, 57 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c96497..6a1c17c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index fa17afd..a1dc83c 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f9eefad..9a5adf7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..de22c98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
@@ -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);
+}
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index f9ad7e8..db9b569 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -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);
diff --git a/gcc/tree-object-size.h b/gcc/tree-object-size.h
index 420af3e..65528b3 100644
--- a/gcc/tree-object-size.h
+++ b/gcc/tree-object-size.h
@@ -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