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/calls.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/calls.c')
-rw-r--r-- | gcc/calls.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 98c6377..e3b4ef8 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1342,9 +1342,10 @@ get_size_range (tree exp, tree range[2], bool allow_zero /* = false */) /* Diagnose a call EXP to function FN decorated with attribute alloc_size whose argument numbers given by IDX with values given by ARGS exceed the maximum object size or cause an unsigned oveflow (wrapping) when - multiplied. When ARGS[0] is null the function does nothing. ARGS[1] - may be null for functions like malloc, and non-null for those like - calloc that are decorated with a two-argument attribute alloc_size. */ + multiplied. FN is null when EXP is a call via a function pointer. + When ARGS[0] is null the function does nothing. ARGS[1] may be null + for functions like malloc, and non-null for those like calloc that + are decorated with a two-argument attribute alloc_size. */ void maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) @@ -1357,6 +1358,8 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) location_t loc = EXPR_LOCATION (exp); + tree fntype = fn ? TREE_TYPE (fn) : TREE_TYPE (TREE_TYPE (exp)); + built_in_function fncode = fn ? DECL_FUNCTION_CODE (fn) : BUILT_IN_NONE; bool warned = false; /* Validate each argument individually. */ @@ -1382,11 +1385,11 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) friends. Also avoid issuing the warning for calls to function named "alloca". */ - if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_ALLOCA + if ((fncode == BUILT_IN_ALLOCA && IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6) - || (DECL_FUNCTION_CODE (fn) != BUILT_IN_ALLOCA + || (fncode != BUILT_IN_ALLOCA && !lookup_attribute ("returns_nonnull", - TYPE_ATTRIBUTES (TREE_TYPE (fn))))) + TYPE_ATTRIBUTES (fntype)))) warned = warning_at (loc, OPT_Walloc_zero, "%Kargument %i value is zero", exp, idx[i] + 1); @@ -1398,6 +1401,7 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) size overflow. There's no good way to detect C++98 here so avoid diagnosing these calls for all C++ modes. */ if (i == 0 + && fn && !args[1] && lang_GNU_CXX () && DECL_IS_OPERATOR_NEW (fn) @@ -1481,7 +1485,7 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) } } - if (warned) + if (warned && fn) { location_t fnloc = DECL_SOURCE_LOCATION (fn); @@ -1933,14 +1937,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, bitmap_obstack_release (NULL); - /* Extract attribute alloc_size and if set, store the indices of - the corresponding arguments in ALLOC_IDX, and then the actual - argument(s) at those indices in ALLOC_ARGS. */ + /* Extract attribute alloc_size from the type of the called expression + (which could be a function or a function pointer) and if set, store + the indices of the corresponding arguments in ALLOC_IDX, and then + the actual argument(s) at those indices in ALLOC_ARGS. */ int alloc_idx[2] = { -1, -1 }; - if (tree alloc_size - = (fndecl ? lookup_attribute ("alloc_size", - TYPE_ATTRIBUTES (TREE_TYPE (fndecl))) - : NULL_TREE)) + if (tree alloc_size = lookup_attribute ("alloc_size", + TYPE_ATTRIBUTES (fntype))) { tree args = TREE_VALUE (alloc_size); alloc_idx[0] = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1; |