diff options
author | Martin Sebor <msebor@redhat.com> | 2019-10-04 21:26:27 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2019-10-04 15:26:27 -0600 |
commit | 28a5fa54aa47877b6d254430adbf3ca0377beeaa (patch) | |
tree | dd44779d5912a216f85020529e623bb2e8acf025 | |
parent | 0e8879cb36eca17e7b1ff8f2124bbc5ec3c6dc91 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/builtins.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wstringop-overflow-17.c | 20 | ||||
-rw-r--r-- | gcc/tree-object-size.c | 33 | ||||
-rw-r--r-- | gcc/tree-object-size.h | 3 |
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 |