aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authormsebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4>2018-12-14 22:45:55 +0000
committermsebor <msebor@138bc75d-0d04-0410-961f-82ee72b054a4>2018-12-14 22:45:55 +0000
commit0f15b7f669e823b8f48ffc6fd3253ad065ff331f (patch)
tree257c476ecc81a6f345864f453f153057cf7f98de /gcc/calls.c
parent2ecb854bf2a95378871dcd2a39a10ca7cc529d45 (diff)
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@267158 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 98c6377d78f..e3b4ef80e51 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;