diff options
Diffstat (limited to 'gcc/c-family/c-warn.c')
-rw-r--r-- | gcc/c-family/c-warn.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 09ef685..6cfded9 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -693,7 +693,8 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee, || vec_safe_length (params) <= 1) return; - switch (DECL_FUNCTION_CODE (callee)) + enum built_in_function fncode = DECL_FUNCTION_CODE (callee); + switch (fncode) { case BUILT_IN_STRNCMP: case BUILT_IN_STRNCASECMP: @@ -775,8 +776,27 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee, type = TYPE_P (sizeof_arg[idx]) ? sizeof_arg[idx] : TREE_TYPE (sizeof_arg[idx]); + if (!POINTER_TYPE_P (type)) - return; + { + /* The argument type may be an array. Diagnose bounded string + copy functions that specify the bound in terms of the source + argument rather than the destination. */ + if (strop && !cmp && fncode != BUILT_IN_STRNDUP && src) + { + tem = tree_strip_nop_conversions (src); + if (TREE_CODE (tem) == ADDR_EXPR) + tem = TREE_OPERAND (tem, 0); + if (operand_equal_p (tem, sizeof_arg[idx], OEP_ADDRESS_OF)) + warning_at (sizeof_arg_loc[idx], OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the source; did you mean to use " + "the size of the destination?", + callee); + } + + return; + } if (dest && (tem = tree_strip_nop_conversions (dest)) |