diff options
author | Martin Sebor <msebor@redhat.com> | 2018-12-14 22:45:55 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2018-12-14 15:45:55 -0700 |
commit | 302db8ba6180906dd9a8c4ce670aff804f921fab (patch) | |
tree | 257c476ecc81a6f345864f453f153057cf7f98de /gcc/tree-object-size.c | |
parent | 3e6837c2a56f47c6b3156bbc12a9e89611412f83 (diff) | |
download | gcc-302db8ba6180906dd9a8c4ce670aff804f921fab.zip gcc-302db8ba6180906dd9a8c4ce670aff804f921fab.tar.gz gcc-302db8ba6180906dd9a8c4ce670aff804f921fab.tar.bz2 |
PR tree-optimization/88372 - alloc_size attribute is ignored on function pointers
gcc/ChangeLog:
PR tree-optimization/88372
* calls.c (maybe_warn_alloc_args_overflow): Handle function pointers.
* tree-object-size.c (alloc_object_size): Same. Simplify.
* doc/extend.texi (Object Size Checking): Update.
(Other Builtins): Add __builtin_object_size.
(Common Type Attributes): Add alloc_size.
(Common Variable Attributes): Ditto.
gcc/testsuite/ChangeLog:
PR tree-optimization/88372
* gcc.dg/Walloc-size-larger-than-18.c: New test.
* gcc.dg/builtin-object-size-19.c: Same.
From-SVN: r267158
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r-- | gcc/tree-object-size.c | 39 |
1 files changed, 15 insertions, 24 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 4f6b230..d925a6c 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -401,25 +401,28 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, /* Compute __builtin_object_size for CALL, which is a GIMPLE_CALL. - Handles various allocation calls. OBJECT_SIZE_TYPE is the second - argument from __builtin_object_size. If unknown, return - unknown[object_size_type]. */ + Handles calls to functions declared with attribute alloc_size. + OBJECT_SIZE_TYPE is the second argument from __builtin_object_size. + If unknown, return unknown[object_size_type]. */ static unsigned HOST_WIDE_INT alloc_object_size (const gcall *call, int object_size_type) { - tree callee, bytes = NULL_TREE; - tree alloc_size; - int arg1 = -1, arg2 = -1; - gcc_assert (is_gimple_call (call)); - callee = gimple_call_fndecl (call); - if (!callee) + tree calltype; + if (tree callfn = gimple_call_fndecl (call)) + calltype = TREE_TYPE (callfn); + else + calltype = gimple_call_fntype (call); + + if (!calltype) return unknown[object_size_type]; - alloc_size = lookup_attribute ("alloc_size", - TYPE_ATTRIBUTES (TREE_TYPE (callee))); + /* Set to positions of alloc_size arguments. */ + int arg1 = -1, arg2 = -1; + tree alloc_size = lookup_attribute ("alloc_size", + TYPE_ATTRIBUTES (calltype)); if (alloc_size && TREE_VALUE (alloc_size)) { tree p = TREE_VALUE (alloc_size); @@ -429,19 +432,6 @@ alloc_object_size (const gcall *call, int object_size_type) arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1; } - if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL) - switch (DECL_FUNCTION_CODE (callee)) - { - case BUILT_IN_CALLOC: - arg2 = 1; - /* fall through */ - case BUILT_IN_MALLOC: - CASE_BUILT_IN_ALLOCA: - arg1 = 0; - default: - break; - } - if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call) || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST || (arg2 >= 0 @@ -449,6 +439,7 @@ alloc_object_size (const gcall *call, int object_size_type) || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST))) return unknown[object_size_type]; + tree bytes = NULL_TREE; if (arg2 >= 0) bytes = size_binop (MULT_EXPR, fold_convert (sizetype, gimple_call_arg (call, arg1)), |