diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-12 18:23:03 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-10-12 18:23:03 +0000 |
commit | 57f872a2a1689ced0b7340178e6984393d07662e (patch) | |
tree | 53a2b873d7fe4f0c44a653a6e7c37c843b92ade2 | |
parent | 25d34a34470da2747013743e6a962f023d7a5868 (diff) | |
download | gcc-57f872a2a1689ced0b7340178e6984393d07662e.tar.gz |
PR c/54381
* c-common.h (sizeof_pointer_memaccess_warning): Adjust prototype.
* c-common.c (sizeof_pointer_memaccess_warning): Take array of 3
locs and array of 3 trees instead of just single loc and single
sizeof_arg tree. Handle __builtin___*_chk builtins too, and
also stpncpy, bcopy, bcmp, bzero, snprintf and vsnprintf builtins.
For *cmp* builtins that take two sources strings report warnings
about first and second source, not about destination and source.
* c-parser.c (struct c_tree_loc_pair): Removed.
(c_parser_expr_list): Remove struct c_tree_loc_pair * argument,
add location_t * and tree * arguments, fill in array of 3
sizeof_arg trees and corresponding locs.
(c_parser_attributes, c_parser_objc_keywordexpr): Adjust
c_parser_expr_list callers.
(c_parser_postfix_expression_after_primary): Likewise. Pass
array of 3 sizeof_arg trees and locs (corresponding to first
3 arguments) to sizeof_pointer_memaccess_warning.
* semantics.c (finish_call_expr): Pass array of 3 sizeof_arg
trees and locs (corresponding to first 3 arguments) to
sizeof_pointer_memaccess_warning.
* c-c++-common/Wsizeof-pointer-memaccess1.c: New test.
* c-c++-common/Wsizeof-pointer-memaccess2.c: New test.
* gcc.dg/Wsizeof-pointer-memaccess1.c: New test.
* gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Test also stpncpy.
Adjust expected wording of warnings for *cmp* builtins.
* g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192406 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/c-family/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 168 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 4 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 71 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c | 161 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c | 482 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C | 112 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C | 116 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c | 456 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c | 112 |
14 files changed, 1543 insertions, 209 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c740e449383..bb82be4d72d 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,14 @@ +2012-10-12 Jakub Jelinek <jakub@redhat.com> + + PR c/54381 + * c-common.h (sizeof_pointer_memaccess_warning): Adjust prototype. + * c-common.c (sizeof_pointer_memaccess_warning): Take array of 3 + locs and array of 3 trees instead of just single loc and single + sizeof_arg tree. Handle __builtin___*_chk builtins too, and + also stpncpy, bcopy, bcmp, bzero, snprintf and vsnprintf builtins. + For *cmp* builtins that take two sources strings report warnings + about first and second source, not about destination and source. + 2012-10-12 Marc Glisse <marc.glisse@inria.fr> PR c++/53055 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index b9186489a40..34cfb98f85b 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -1847,52 +1847,105 @@ strict_aliasing_warning (tree otype, tree type, tree expr) sizeof as last operand of certain builtins. */ void -sizeof_pointer_memaccess_warning (location_t loc, tree callee, - VEC(tree, gc) *params, tree sizeof_arg, +sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee, + VEC(tree, gc) *params, tree *sizeof_arg, bool (*comp_types) (tree, tree)) { tree type, dest = NULL_TREE, src = NULL_TREE, tem; - bool strop = false; + bool strop = false, cmp = false; + unsigned int idx = ~0; + location_t loc; if (TREE_CODE (callee) != FUNCTION_DECL || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL - || sizeof_arg == error_mark_node || VEC_length (tree, params) <= 1) return; - type = TYPE_P (sizeof_arg) ? sizeof_arg : TREE_TYPE (sizeof_arg); - if (!POINTER_TYPE_P (type)) - return; - switch (DECL_FUNCTION_CODE (callee)) { case BUILT_IN_STRNCMP: case BUILT_IN_STRNCASECMP: + cmp = true; + /* FALLTHRU */ case BUILT_IN_STRNCPY: + case BUILT_IN_STRNCPY_CHK: case BUILT_IN_STRNCAT: + case BUILT_IN_STRNCAT_CHK: + case BUILT_IN_STPNCPY: + case BUILT_IN_STPNCPY_CHK: strop = true; /* FALLTHRU */ case BUILT_IN_MEMCPY: + case BUILT_IN_MEMCPY_CHK: case BUILT_IN_MEMMOVE: + case BUILT_IN_MEMMOVE_CHK: + if (VEC_length (tree, params) < 3) + return; + src = VEC_index (tree, params, 1); + dest = VEC_index (tree, params, 0); + idx = 2; + break; + case BUILT_IN_BCOPY: + if (VEC_length (tree, params) < 3) + return; + src = VEC_index (tree, params, 0); + dest = VEC_index (tree, params, 1); + idx = 2; + break; case BUILT_IN_MEMCMP: + case BUILT_IN_BCMP: if (VEC_length (tree, params) < 3) return; src = VEC_index (tree, params, 1); dest = VEC_index (tree, params, 0); + idx = 2; + cmp = true; break; case BUILT_IN_MEMSET: + case BUILT_IN_MEMSET_CHK: if (VEC_length (tree, params) < 3) return; dest = VEC_index (tree, params, 0); + idx = 2; + break; + case BUILT_IN_BZERO: + dest = VEC_index (tree, params, 0); + idx = 1; break; case BUILT_IN_STRNDUP: src = VEC_index (tree, params, 0); strop = true; + idx = 1; + break; + case BUILT_IN_MEMCHR: + if (VEC_length (tree, params) < 3) + return; + src = VEC_index (tree, params, 0); + idx = 2; + break; + case BUILT_IN_SNPRINTF: + case BUILT_IN_SNPRINTF_CHK: + case BUILT_IN_VSNPRINTF: + case BUILT_IN_VSNPRINTF_CHK: + dest = VEC_index (tree, params, 0); + idx = 1; + strop = true; break; default: break; } + if (idx >= 3) + return; + + if (sizeof_arg[idx] == NULL || sizeof_arg[idx] == error_mark_node) + return; + + type = TYPE_P (sizeof_arg[idx]) + ? sizeof_arg[idx] : TREE_TYPE (sizeof_arg[idx]); + if (!POINTER_TYPE_P (type)) + return; + if (dest && (tem = tree_strip_nop_conversions (dest)) && POINTER_TYPE_P (TREE_TYPE (tem)) @@ -1905,13 +1958,15 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee, && comp_types (TREE_TYPE (TREE_TYPE (tem)), type)) return; - if (dest) + loc = sizeof_arg_loc[idx]; + + if (dest && !cmp) { - if (!TYPE_P (sizeof_arg) - && operand_equal_p (dest, sizeof_arg, 0) + if (!TYPE_P (sizeof_arg[idx]) + && operand_equal_p (dest, sizeof_arg[idx], 0) && comp_types (TREE_TYPE (dest), type)) { - if (TREE_CODE (sizeof_arg) == ADDR_EXPR && !strop) + if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) warning_at (loc, OPT_Wsizeof_pointer_memaccess, "argument to %<sizeof%> in %qD call is the same " "expression as the destination; did you mean to " @@ -1945,13 +2000,13 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee, } } - if (src) + if (src && !cmp) { - if (!TYPE_P (sizeof_arg) - && operand_equal_p (src, sizeof_arg, 0) + if (!TYPE_P (sizeof_arg[idx]) + && operand_equal_p (src, sizeof_arg[idx], 0) && comp_types (TREE_TYPE (src), type)) { - if (TREE_CODE (sizeof_arg) == ADDR_EXPR && !strop) + if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) warning_at (loc, OPT_Wsizeof_pointer_memaccess, "argument to %<sizeof%> in %qD call is the same " "expression as the source; did you mean to " @@ -1984,6 +2039,87 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee, return; } } + + if (dest) + { + if (!TYPE_P (sizeof_arg[idx]) + && operand_equal_p (dest, sizeof_arg[idx], 0) + && comp_types (TREE_TYPE (dest), type)) + { + if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the first source; did you mean to " + "remove the addressof?", callee); + else if ((TYPE_PRECISION (TREE_TYPE (type)) + == TYPE_PRECISION (char_type_node)) + || strop) + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the first source; did you mean to " + "provide an explicit length?", callee); + else + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the first source; did you mean to " + "dereference it?", callee); + return; + } + + if (POINTER_TYPE_P (TREE_TYPE (dest)) + && !strop + && comp_types (TREE_TYPE (dest), type) + && !VOID_TYPE_P (TREE_TYPE (type))) + { + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "pointer type %qT as the first source; expected %qT " + "or an explicit length", callee, TREE_TYPE (dest), + TREE_TYPE (TREE_TYPE (dest))); + return; + } + } + + if (src) + { + if (!TYPE_P (sizeof_arg[idx]) + && operand_equal_p (src, sizeof_arg[idx], 0) + && comp_types (TREE_TYPE (src), type)) + { + if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop) + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the second source; did you mean to " + "remove the addressof?", callee); + else if ((TYPE_PRECISION (TREE_TYPE (type)) + == TYPE_PRECISION (char_type_node)) + || strop) + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the second source; did you mean to " + "provide an explicit length?", callee); + else + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "expression as the second source; did you mean to " + "dereference it?", callee); + return; + } + + if (POINTER_TYPE_P (TREE_TYPE (src)) + && !strop + && comp_types (TREE_TYPE (src), type) + && !VOID_TYPE_P (TREE_TYPE (type))) + { + warning_at (loc, OPT_Wsizeof_pointer_memaccess, + "argument to %<sizeof%> in %qD call is the same " + "pointer type %qT as the second source; expected %qT " + "or an explicit length", callee, TREE_TYPE (src), + TREE_TYPE (TREE_TYPE (src))); + return; + } + } + } /* Warn for unlikely, improbable, or stupid DECL declarations diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 66d90a34570..94449a5f3f3 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -769,8 +769,8 @@ extern tree fix_string_type (tree); extern void constant_expression_warning (tree); extern void constant_expression_error (tree); extern bool strict_aliasing_warning (tree, tree, tree); -extern void sizeof_pointer_memaccess_warning (location_t, tree, - VEC(tree, gc) *, tree, +extern void sizeof_pointer_memaccess_warning (location_t *, tree, + VEC(tree, gc) *, tree *, bool (*) (tree, tree)); extern void warnings_for_convert_and_check (tree, tree, tree); extern tree convert_and_check (tree, tree); diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index dfe76e63fda..89d89f7aca2 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,16 @@ +2012-10-12 Jakub Jelinek <jakub@redhat.com> + + PR c/54381 + * c-parser.c (struct c_tree_loc_pair): Removed. + (c_parser_expr_list): Remove struct c_tree_loc_pair * argument, + add location_t * and tree * arguments, fill in array of 3 + sizeof_arg trees and corresponding locs. + (c_parser_attributes, c_parser_objc_keywordexpr): Adjust + c_parser_expr_list callers. + (c_parser_postfix_expression_after_primary): Likewise. Pass + array of 3 sizeof_arg trees and locs (corresponding to first + 3 arguments) to sizeof_pointer_memaccess_warning. + 2012-10-09 Lawrence Crowl <crowl@google.com> * Make-lang.in (c-decl.o): Add dependence on hash-table.h. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index bea9791925c..bfa98afef01 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1111,12 +1111,6 @@ enum c_parser_prec { NUM_PRECS }; -/* Expression and its location. */ -struct c_tree_loc_pair { - tree expr; - location_t loc; -}; - static void c_parser_external_declaration (c_parser *); static void c_parser_asm_definition (c_parser *); static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, @@ -1185,8 +1179,8 @@ static tree c_parser_transaction_cancel (c_parser *); static struct c_expr c_parser_expression (c_parser *); static struct c_expr c_parser_expression_conv (c_parser *); static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool, - VEC(tree,gc) **, - struct c_tree_loc_pair *); + VEC(tree,gc) **, location_t *, + tree *); static void c_parser_omp_construct (c_parser *); static void c_parser_omp_threadprivate (c_parser *); static void c_parser_omp_barrier (c_parser *); @@ -3586,7 +3580,7 @@ c_parser_attributes (c_parser *parser) tree tree_list; c_parser_consume_token (parser); expr_list = c_parser_expr_list (parser, false, true, - NULL, NULL); + NULL, NULL, NULL); tree_list = build_tree_list_vec (expr_list); attr_args = tree_cons (NULL_TREE, arg1, tree_list); release_tree_vector (expr_list); @@ -3599,7 +3593,7 @@ c_parser_attributes (c_parser *parser) else { expr_list = c_parser_expr_list (parser, false, true, - NULL, NULL); + NULL, NULL, NULL); attr_args = build_tree_list_vec (expr_list); release_tree_vector (expr_list); } @@ -6875,7 +6869,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser, { struct c_expr orig_expr; tree ident, idx; - struct c_tree_loc_pair sizeof_arg; + location_t sizeof_arg_loc[3]; + tree sizeof_arg[3]; + unsigned int i; VEC(tree,gc) *exprlist; VEC(tree,gc) *origtypes; while (true) @@ -6896,21 +6892,24 @@ c_parser_postfix_expression_after_primary (c_parser *parser, case CPP_OPEN_PAREN: /* Function call. */ c_parser_consume_token (parser); - sizeof_arg.expr = NULL_TREE; + for (i = 0; i < 3; i++) + { + sizeof_arg[i] = NULL_TREE; + sizeof_arg_loc[i] = UNKNOWN_LOCATION; + } if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) exprlist = NULL; else exprlist = c_parser_expr_list (parser, true, false, &origtypes, - &sizeof_arg); + sizeof_arg_loc, sizeof_arg); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); orig_expr = expr; mark_exp_read (expr.value); - if (warn_sizeof_pointer_memaccess - && sizeof_arg.expr != NULL_TREE) - sizeof_pointer_memaccess_warning (sizeof_arg.loc, + if (warn_sizeof_pointer_memaccess) + sizeof_pointer_memaccess_warning (sizeof_arg_loc, expr.value, exprlist, - sizeof_arg.expr, + sizeof_arg, sizeof_ptr_memacc_comptypes); /* FIXME diagnostics: Ideally we want the FUNCNAME, not the "(" after the FUNCNAME, which is what we have now. */ @@ -7072,14 +7071,15 @@ c_parser_expression_conv (c_parser *parser) static VEC(tree,gc) * c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, - VEC(tree,gc) **p_orig_types, - struct c_tree_loc_pair *sizeof_arg) + VEC(tree,gc) **p_orig_types, location_t *sizeof_arg_loc, + tree *sizeof_arg) { VEC(tree,gc) *ret; VEC(tree,gc) *orig_types; struct c_expr expr; location_t loc = c_parser_peek_token (parser)->location; - location_t sizeof_arg_loc = UNKNOWN_LOCATION; + location_t cur_sizeof_arg_loc = UNKNOWN_LOCATION; + unsigned int idx = 0; ret = make_tree_vector (); if (p_orig_types == NULL) @@ -7089,7 +7089,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, if (sizeof_arg != NULL && c_parser_next_token_is_keyword (parser, RID_SIZEOF)) - sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location; + cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location; expr = c_parser_expr_no_commas (parser, NULL); if (convert_p) expr = default_function_array_read_conversion (loc, expr); @@ -7098,15 +7098,22 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, VEC_quick_push (tree, ret, expr.value); if (orig_types != NULL) VEC_quick_push (tree, orig_types, expr.original_type); + if (sizeof_arg != NULL + && cur_sizeof_arg_loc != UNKNOWN_LOCATION + && expr.original_code == SIZEOF_EXPR) + { + sizeof_arg[0] = c_last_sizeof_arg; + sizeof_arg_loc[0] = cur_sizeof_arg_loc; + } while (c_parser_next_token_is (parser, CPP_COMMA)) { c_parser_consume_token (parser); loc = c_parser_peek_token (parser)->location; if (sizeof_arg != NULL && c_parser_next_token_is_keyword (parser, RID_SIZEOF)) - sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location; + cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location; else - sizeof_arg_loc = UNKNOWN_LOCATION; + cur_sizeof_arg_loc = UNKNOWN_LOCATION; expr = c_parser_expr_no_commas (parser, NULL); if (convert_p) expr = default_function_array_read_conversion (loc, expr); @@ -7115,19 +7122,13 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, VEC_safe_push (tree, gc, ret, expr.value); if (orig_types != NULL) VEC_safe_push (tree, gc, orig_types, expr.original_type); - } - if (sizeof_arg != NULL) - { - if (sizeof_arg_loc != UNKNOWN_LOCATION + if (++idx < 3 + && sizeof_arg != NULL + && cur_sizeof_arg_loc != UNKNOWN_LOCATION && expr.original_code == SIZEOF_EXPR) { - sizeof_arg->expr = c_last_sizeof_arg; - sizeof_arg->loc = sizeof_arg_loc; - } - else - { - sizeof_arg->expr = NULL_TREE; - sizeof_arg->loc = UNKNOWN_LOCATION; + sizeof_arg[idx] = c_last_sizeof_arg; + sizeof_arg_loc[idx] = cur_sizeof_arg_loc; } } if (orig_types != NULL) @@ -8209,7 +8210,7 @@ c_parser_objc_keywordexpr (c_parser *parser) { tree ret; VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, - NULL, NULL); + NULL, NULL, NULL); if (VEC_length (tree, expr_list) == 1) { /* Just return the expression, remove a level of diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6730b109378..27f0d55ac97 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-10-12 Jakub Jelinek <jakub@redhat.com> + + PR c/54381 + * semantics.c (finish_call_expr): Pass array of 3 sizeof_arg + trees and locs (corresponding to first 3 arguments) to + sizeof_pointer_memaccess_warning. + 2012-10-12 Paolo Carlini <paolo.carlini@oracle.com> PR c++/24449 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 4beed0073fb..6798c1bf5d4 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2173,16 +2173,30 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual, { if (warn_sizeof_pointer_memaccess && !VEC_empty(tree, *args) - && TREE_CODE (VEC_last(tree, *args)) == SIZEOF_EXPR && !processing_template_decl) { - tree sizeof_arg = VEC_last(tree, *args); - if (SIZEOF_EXPR_TYPE_P (sizeof_arg)) - sizeof_arg = TREE_TYPE (TREE_OPERAND (sizeof_arg, 0)); - else - sizeof_arg = TREE_OPERAND (sizeof_arg, 0); + location_t sizeof_arg_loc[3]; + tree sizeof_arg[3]; + unsigned int i; + for (i = 0; i < 3; i++) + { + tree t; + + sizeof_arg_loc[i] = UNKNOWN_LOCATION; + sizeof_arg[i] = NULL_TREE; + if (i >= VEC_length (tree, *args)) + continue; + t = VEC_index (tree, *args, i); + if (TREE_CODE (t) != SIZEOF_EXPR) + continue; + if (SIZEOF_EXPR_TYPE_P (t)) + sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0)); + else + sizeof_arg[i] = TREE_OPERAND (t, 0); + sizeof_arg_loc[i] = EXPR_LOCATION (t); + } sizeof_pointer_memaccess_warning - (EXPR_LOCATION (VEC_last(tree, *args)), fn, *args, + (sizeof_arg_loc, fn, *args, sizeof_arg, same_type_ignoring_top_level_qualifiers_p); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 862b4273055..0faa27b8b2a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2012-10-12 Jakub Jelinek <jakub@redhat.com> + + PR c/54381 + * c-c++-common/Wsizeof-pointer-memaccess1.c: New test. + * c-c++-common/Wsizeof-pointer-memaccess2.c: New test. + * gcc.dg/Wsizeof-pointer-memaccess1.c: New test. + * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Test also stpncpy. + Adjust expected wording of warnings for *cmp* builtins. + * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise. + * g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise. + 2012-10-12 Paolo Carlini <paolo.carlini@oracle.com> PR c++/24449 diff --git a/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c new file mode 100644 index 00000000000..2a5f4193b21 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c @@ -0,0 +1,161 @@ +/* Test -Wsizeof-pointer-memaccess warnings. */ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +typedef __SIZE_TYPE__ size_t; +#ifdef __cplusplus +extern "C" { +#endif +extern int snprintf (char *, size_t, const char *, ...); +extern int vsnprintf (char *, size_t, const char *, __builtin_va_list); +extern void *memchr (const void *, int, size_t); +#ifdef __cplusplus +} +#endif + +struct A { short a, b; int c, d; long e, f; }; +typedef struct A TA; +typedef struct A *PA; +typedef TA *PTA; +struct B {}; +typedef struct B TB; +typedef struct B *PB; +typedef TB *PTB; +typedef int X[3][3][3]; + +void foo (void **); + +void +f1 (void *x) +{ + struct A a, *pa1 = &a; + TA *pa2 = &a; + PA pa3 = &a; + PTA pa4 = &a; + void *arr[100]; + int i = 0; + arr[i++] = memchr (&a, 0, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + arr[i++] = memchr (pa1, 0, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pa2, 0, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pa3, 0, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pa4, 0, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pa1, 0, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + arr[i++] = memchr (pa2, 0, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + arr[i++] = memchr (pa3, 0, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + arr[i++] = memchr (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + /* These are correct, no warning. */ + arr[i++] = memchr (&a, 0, sizeof a); + arr[i++] = memchr (&a, 0, sizeof (a)); + arr[i++] = memchr (&a, 0, sizeof (struct A)); + arr[i++] = memchr (&a, 0, sizeof (const struct A)); + arr[i++] = memchr (&a, 0, sizeof (volatile struct A)); + arr[i++] = memchr (&a, 0, sizeof (volatile const struct A)); + arr[i++] = memchr (&a, 0, sizeof (TA)); + arr[i++] = memchr (&a, 0, sizeof (__typeof (*&a))); + arr[i++] = memchr (pa1, 0, sizeof (*pa1)); + arr[i++] = memchr (pa2, 0, sizeof (*pa3)); + arr[i++] = memchr (pa3, 0, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + arr[i++] = memchr ((void *) &a, 0, sizeof (&a)); + arr[i++] = memchr ((char *) &a, 0, sizeof (&a)); + arr[i++] = memchr (&a, 0, sizeof (&a) + 0); + arr[i++] = memchr (&a, 0, 0 + sizeof (&a)); + + foo (arr); +} + +void +f2 (void *x) +{ + struct B b, *pb1 = &b; + TB *pb2 = &b; + PB pb3 = &b; + PTB pb4 = &b; + void *arr[100]; + int i = 0; + arr[i++] = memchr (&b, 0, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + arr[i++] = memchr (pb1, 0, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pb2, 0, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pb3, 0, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pb4, 0, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + arr[i++] = memchr (pb1, 0, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + arr[i++] = memchr (pb2, 0, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + arr[i++] = memchr (pb3, 0, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + arr[i++] = memchr (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + /* These are correct, no warning. */ + arr[i++] = memchr (&b, 0, sizeof b); + arr[i++] = memchr (&b, 0, sizeof (b)); + arr[i++] = memchr (&b, 0, sizeof (struct B)); + arr[i++] = memchr (&b, 0, sizeof (const struct B)); + arr[i++] = memchr (&b, 0, sizeof (volatile struct B)); + arr[i++] = memchr (&b, 0, sizeof (volatile const struct B)); + arr[i++] = memchr (&b, 0, sizeof (TB)); + arr[i++] = memchr (&b, 0, sizeof (__typeof (*&b))); + arr[i++] = memchr (pb1, 0, sizeof (*pb1)); + arr[i++] = memchr (pb2, 0, sizeof (*pb3)); + arr[i++] = memchr (pb3, 0, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + arr[i++] = memchr ((void *) &b, 0, sizeof (&b)); + arr[i++] = memchr ((char *) &b, 0, sizeof (&b)); + arr[i++] = memchr (&b, 0, sizeof (&b) + 0); + arr[i++] = memchr (&b, 0, 0 + sizeof (&b)); + + foo (arr); +} + +void +f3 (void *x, char *y, int z, X w) +{ + unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16); + char buf1[7]; + signed char buf2[z + 32]; + long buf3[17]; + int *buf4[9]; + signed char *y2 = buf2; + char c; + void *arr[100]; + int i = 0; + arr[i++] = memchr (y, 0, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + arr[i++] = memchr (y1, 0, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + arr[i++] = memchr (y2, 0, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + arr[i++] = memchr (&c, 0, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + arr[i++] = memchr (w, 0, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + + /* These are correct, no warning. */ + arr[i++] = memchr (y, 0, sizeof (*y)); + arr[i++] = memchr (y1, 0, sizeof (*y2)); + arr[i++] = memchr (buf1, 0, sizeof buf1); + arr[i++] = memchr (buf3, 0, sizeof (buf3)); + arr[i++] = memchr (&buf3[0], 0, sizeof (buf3)); + arr[i++] = memchr (&buf4[0], 0, sizeof (buf4)); + arr[i++] = memchr (w, 0, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + arr[i++] = memchr ((void *) y, 0, sizeof (y)); + arr[i++] = memchr ((char *) y1, 0, sizeof (y2)); + arr[i++] = memchr (y, 0, sizeof (y) + 0); + arr[i++] = memchr (y1, 0, 0 + sizeof (y2)); + arr[i++] = memchr ((void *) &c, 0, sizeof (&c)); + arr[i++] = memchr ((signed char *) &c, 0, sizeof (&c)); + arr[i++] = memchr (&c, 0, sizeof (&c) + 0); + arr[i++] = memchr (&c, 0, 0 + sizeof (&c)); + + foo (arr); +} + +void +f4 (char x[64], char *y, __builtin_va_list ap) +{ + char buf[128], *p = buf; + snprintf (x, sizeof (x), "%s", y); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + vsnprintf (x, sizeof (x), "%s", ap); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + snprintf (p, sizeof (p), "%s", y); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + vsnprintf (p, sizeof (p), "%s", ap); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + + /* These are correct, no warning. */ + snprintf (buf, sizeof (buf), "%s", y); + vsnprintf (buf, sizeof (buf), "%s", ap); + snprintf (p, sizeof (buf), "%s", y); + vsnprintf (p, sizeof (buf), "%s", ap); +} diff --git a/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c new file mode 100644 index 00000000000..73cdf0eaba7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c @@ -0,0 +1,482 @@ +/* Test -Wsizeof-pointer-memaccess warnings. */ +/* { dg-do compile } */ +/* { dg-options "-Wall -O2" } */ + +#define bos(ptr) __builtin_object_size (ptr, 1) +#define bos0(ptr) __builtin_object_size (ptr, 0) + +#define memset(dst, val, sz) __builtin___memset_chk (dst, val, sz, bos (dst)) +#define memcpy(dst, src, sz) __builtin___memcpy_chk (dst, src, sz, bos (dst)) +#define memmove(dst, src, sz) __builtin___memmove_chk (dst, src, sz, bos (dst)) +#define strncpy(dst, src, sz) __builtin___strncpy_chk (dst, src, sz, bos (dst)) +#define strncat(dst, src, sz) __builtin___strncat_chk (dst, src, sz, bos (dst)) +#define stpncpy(dst, src, sz) __builtin___stpncpy_chk (dst, src, sz, bos (dst)) + +struct A { short a, b; int c, d; long e, f; }; +typedef struct A TA; +typedef struct A *PA; +typedef TA *PTA; +struct B {}; +typedef struct B TB; +typedef struct B *PB; +typedef TB *PTB; +typedef int X[3][3][3]; + +void +f1 (void *x) +{ + struct A a, *pa1 = &a; + TA *pa2 = &a; + PA pa3 = &a; + PTA pa4 = &a; + memset (&a, 0, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memset (pa1, 0, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pa2, 0, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pa3, 0, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pa4, 0, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pa1, 0, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memset (pa2, 0, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memset (pa3, 0, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memset (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + memcpy (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memcpy (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memcpy (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memcpy (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memcpy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + memcpy (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + memcpy (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memcpy (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memcpy (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memcpy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + memmove (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memmove (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memmove (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memmove (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memmove (pa4, x, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + memmove (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + memmove (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memmove (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memmove (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + /* These are correct, no warning. */ + memset (&a, 0, sizeof a); + memset (&a, 0, sizeof (a)); + memset (&a, 0, sizeof (struct A)); + memset (&a, 0, sizeof (const struct A)); + memset (&a, 0, sizeof (volatile struct A)); + memset (&a, 0, sizeof (volatile const struct A)); + memset (&a, 0, sizeof (TA)); + memset (&a, 0, sizeof (__typeof (*&a))); + memset (pa1, 0, sizeof (*pa1)); + memset (pa2, 0, sizeof (*pa3)); + memset (pa3, 0, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + memset ((void *) &a, 0, sizeof (&a)); + memset ((char *) &a, 0, sizeof (&a)); + memset (&a, 0, sizeof (&a) + 0); + memset (&a, 0, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + memcpy (&a, x, sizeof a); + memcpy (&a, x, sizeof (a)); + memcpy (&a, x, sizeof (struct A)); + memcpy (&a, x, sizeof (const struct A)); + memcpy (&a, x, sizeof (volatile struct A)); + memcpy (&a, x, sizeof (volatile const struct A)); + memcpy (&a, x, sizeof (TA)); + memcpy (&a, x, sizeof (__typeof (*&a))); + memcpy (pa1, x, sizeof (*pa1)); + memcpy (pa2, x, sizeof (*pa3)); + memcpy (pa3, x, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + memcpy ((void *) &a, x, sizeof (&a)); + memcpy ((char *) &a, x, sizeof (&a)); + memcpy (&a, x, sizeof (&a) + 0); + memcpy (&a, x, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + memcpy (x, &a, sizeof a); + memcpy (x, &a, sizeof (a)); + memcpy (x, &a, sizeof (struct A)); + memcpy (x, &a, sizeof (const struct A)); + memcpy (x, &a, sizeof (volatile struct A)); + memcpy (x, &a, sizeof (volatile const struct A)); + memcpy (x, &a, sizeof (TA)); + memcpy (x, &a, sizeof (__typeof (*&a))); + memcpy (x, pa1, sizeof (*pa1)); + memcpy (x, pa2, sizeof (*pa3)); + memcpy (x, pa3, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + memcpy (x, (void *) &a, sizeof (&a)); + memcpy (x, (char *) &a, sizeof (&a)); + memcpy (x, &a, sizeof (&a) + 0); + memcpy (x, &a, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + memmove (&a, x, sizeof a); + memmove (&a, x, sizeof (a)); + memmove (&a, x, sizeof (struct A)); + memmove (&a, x, sizeof (const struct A)); + memmove (&a, x, sizeof (volatile struct A)); + memmove (&a, x, sizeof (volatile const struct A)); + memmove (&a, x, sizeof (TA)); + memmove (&a, x, sizeof (__typeof (*&a))); + memmove (pa1, x, sizeof (*pa1)); + memmove (pa2, x, sizeof (*pa3)); + memmove (pa3, x, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + memmove ((void *) &a, x, sizeof (&a)); + memmove ((char *) &a, x, sizeof (&a)); + memmove (&a, x, sizeof (&a) + 0); + memmove (&a, x, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + memmove (x, &a, sizeof a); + memmove (x, &a, sizeof (a)); + memmove (x, &a, sizeof (struct A)); + memmove (x, &a, sizeof (const struct A)); + memmove (x, &a, sizeof (volatile struct A)); + memmove (x, &a, sizeof (volatile const struct A)); + memmove (x, &a, sizeof (TA)); + memmove (x, &a, sizeof (__typeof (*&a))); + memmove (x, pa1, sizeof (*pa1)); + memmove (x, pa2, sizeof (*pa3)); + memmove (x, pa3, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + memmove (x, (void *) &a, sizeof (&a)); + memmove (x, (char *) &a, sizeof (&a)); + memmove (x, &a, sizeof (&a) + 0); + memmove (x, &a, 0 + sizeof (&a)); +} + +void +f2 (void *x) +{ + struct B b, *pb1 = &b; + TB *pb2 = &b; + PB pb3 = &b; + PTB pb4 = &b; + memset (&b, 0, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memset (pb1, 0, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pb2, 0, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pb3, 0, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pb4, 0, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memset (pb1, 0, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memset (pb2, 0, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memset (pb3, 0, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memset (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + memcpy (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memcpy (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memcpy (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memcpy (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memcpy (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memcpy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + memcpy (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + memcpy (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memcpy (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memcpy (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memcpy (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memcpy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + memmove (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memmove (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + memmove (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memmove (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memmove (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + memmove (pb4, x, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + memmove (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + memmove (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + memmove (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memmove (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memmove (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + /* These are correct, no warning. */ + memset (&b, 0, sizeof b); + memset (&b, 0, sizeof (b)); + memset (&b, 0, sizeof (struct B)); + memset (&b, 0, sizeof (const struct B)); + memset (&b, 0, sizeof (volatile struct B)); + memset (&b, 0, sizeof (volatile const struct B)); + memset (&b, 0, sizeof (TB)); + memset (&b, 0, sizeof (__typeof (*&b))); + memset (pb1, 0, sizeof (*pb1)); + memset (pb2, 0, sizeof (*pb3)); + memset (pb3, 0, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + memset ((void *) &b, 0, sizeof (&b)); + memset ((char *) &b, 0, sizeof (&b)); + memset (&b, 0, sizeof (&b) + 0); + memset (&b, 0, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + memcpy (&b, x, sizeof b); + memcpy (&b, x, sizeof (b)); + memcpy (&b, x, sizeof (struct B)); + memcpy (&b, x, sizeof (const struct B)); + memcpy (&b, x, sizeof (volatile struct B)); + memcpy (&b, x, sizeof (volatile const struct B)); + memcpy (&b, x, sizeof (TB)); + memcpy (&b, x, sizeof (__typeof (*&b))); + memcpy (pb1, x, sizeof (*pb1)); + memcpy (pb2, x, sizeof (*pb3)); + memcpy (pb3, x, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + memcpy ((void *) &b, x, sizeof (&b)); + memcpy ((char *) &b, x, sizeof (&b)); + memcpy (&b, x, sizeof (&b) + 0); + memcpy (&b, x, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + memcpy (x, &b, sizeof b); + memcpy (x, &b, sizeof (b)); + memcpy (x, &b, sizeof (struct B)); + memcpy (x, &b, sizeof (const struct B)); + memcpy (x, &b, sizeof (volatile struct B)); + memcpy (x, &b, sizeof (volatile const struct B)); + memcpy (x, &b, sizeof (TB)); + memcpy (x, &b, sizeof (__typeof (*&b))); + memcpy (x, pb1, sizeof (*pb1)); + memcpy (x, pb2, sizeof (*pb3)); + memcpy (x, pb3, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + memcpy (x, (void *) &b, sizeof (&b)); + memcpy (x, (char *) &b, sizeof (&b)); + memcpy (x, &b, sizeof (&b) + 0); + memcpy (x, &b, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + memmove (&b, x, sizeof b); + memmove (&b, x, sizeof (b)); + memmove (&b, x, sizeof (struct B)); + memmove (&b, x, sizeof (const struct B)); + memmove (&b, x, sizeof (volatile struct B)); + memmove (&b, x, sizeof (volatile const struct B)); + memmove (&b, x, sizeof (TB)); + memmove (&b, x, sizeof (__typeof (*&b))); + memmove (pb1, x, sizeof (*pb1)); + memmove (pb2, x, sizeof (*pb3)); + memmove (pb3, x, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + memmove ((void *) &b, x, sizeof (&b)); + memmove ((char *) &b, x, sizeof (&b)); + memmove (&b, x, sizeof (&b) + 0); + memmove (&b, x, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + memmove (x, &b, sizeof b); + memmove (x, &b, sizeof (b)); + memmove (x, &b, sizeof (struct B)); + memmove (x, &b, sizeof (const struct B)); + memmove (x, &b, sizeof (volatile struct B)); + memmove (x, &b, sizeof (volatile const struct B)); + memmove (x, &b, sizeof (TB)); + memmove (x, &b, sizeof (__typeof (*&b))); + memmove (x, pb1, sizeof (*pb1)); + memmove (x, pb2, sizeof (*pb3)); + memmove (x, pb3, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + memmove (x, (void *) &b, sizeof (&b)); + memmove (x, (char *) &b, sizeof (&b)); + memmove (x, &b, sizeof (&b) + 0); + memmove (x, &b, 0 + sizeof (&b)); +} + +void +f3 (void *x, char *y, int z, X w) +{ + unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16); + char buf1[7]; + signed char buf2[z + 32]; + long buf3[17]; + int *buf4[9]; + signed char *y2 = buf2; + char c; + char *y3; + memset (y, 0, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memset (y1, 0, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memset (y2, 0, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memset (&c, 0, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memset (w, 0, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + + memcpy (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memcpy (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memcpy (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memcpy (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memcpy (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + + memcpy (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + memcpy (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + memcpy (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + memcpy (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + memcpy (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + + memmove (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memmove (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memmove (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + memmove (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + memmove (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + + memmove (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + memmove (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + memmove (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + memmove (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + memmove (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + + /* These are correct, no warning. */ + memset (y, 0, sizeof (*y)); + memset (y1, 0, sizeof (*y2)); + memset (buf1, 0, sizeof buf1); + memset (buf3, 0, sizeof (buf3)); + memset (&buf3[0], 0, sizeof (buf3)); + memset (&buf4[0], 0, sizeof (buf4)); + memset (w, 0, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + memset ((void *) y, 0, sizeof (y)); + memset ((char *) y1, 0, sizeof (y2)); + memset (y, 0, sizeof (y) + 0); + memset (y1, 0, 0 + sizeof (y2)); + memset ((void *) &c, 0, sizeof (&c)); + memset ((signed char *) &c, 0, sizeof (&c)); + memset (&c, 0, sizeof (&c) + 0); + memset (&c, 0, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + memcpy (y, x, sizeof (*y)); + memcpy (y1, x, sizeof (*y2)); + memcpy (buf1, x, sizeof buf1); + memcpy (buf3, x, sizeof (buf3)); + memcpy (&buf3[0], x, sizeof (buf3)); + memcpy (&buf4[0], x, sizeof (buf4)); + memcpy (&y3, y, sizeof (y3)); + memcpy ((char *) &y3, y, sizeof (y3)); + memcpy (w, x, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + memcpy ((void *) y, x, sizeof (y)); + memcpy ((char *) y1, x, sizeof (y2)); + memcpy (y, x, sizeof (y) + 0); + memcpy (y1, x, 0 + sizeof (y2)); + memcpy ((void *) &c, x, sizeof (&c)); + memcpy ((signed char *) &c, x, sizeof (&c)); + memcpy (&c, x, sizeof (&c) + 0); + memcpy (&c, x, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + memcpy (x, y, sizeof (*y)); + memcpy (x, y1, sizeof (*y2)); + memcpy (x, buf1, sizeof buf1); + memcpy (x, buf3, sizeof (buf3)); + memcpy (x, &buf3[0], sizeof (buf3)); + memcpy (x, &buf4[0], sizeof (buf4)); + memcpy (y, &y3, sizeof (y3)); + memcpy (y, (char *) &y3, sizeof (y3)); + memcpy (x, w, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + memcpy (x, (void *) y, sizeof (y)); + memcpy (x, (char *) y1, sizeof (y2)); + memcpy (x, y, sizeof (y) + 0); + memcpy (x, y1, 0 + sizeof (y2)); + memcpy (x, (void *) &c, sizeof (&c)); + memcpy (x, (signed char *) &c, sizeof (&c)); + memcpy (x, &c, sizeof (&c) + 0); + memcpy (x, &c, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + memmove (y, x, sizeof (*y)); + memmove (y1, x, sizeof (*y2)); + memmove (buf1, x, sizeof buf1); + memmove (buf3, x, sizeof (buf3)); + memmove (&buf3[0], x, sizeof (buf3)); + memmove (&buf4[0], x, sizeof (buf4)); + memmove (&y3, y, sizeof (y3)); + memmove ((char *) &y3, y, sizeof (y3)); + memmove (w, x, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + memmove ((void *) y, x, sizeof (y)); + memmove ((char *) y1, x, sizeof (y2)); + memmove (y, x, sizeof (y) + 0); + memmove (y1, x, 0 + sizeof (y2)); + memmove ((void *) &c, x, sizeof (&c)); + memmove ((signed char *) &c, x, sizeof (&c)); + memmove (&c, x, sizeof (&c) + 0); + memmove (&c, x, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + memmove (x, y, sizeof (*y)); + memmove (x, y1, sizeof (*y2)); + memmove (x, buf1, sizeof buf1); + memmove (x, buf3, sizeof (buf3)); + memmove (x, &buf3[0], sizeof (buf3)); + memmove (x, &buf4[0], sizeof (buf4)); + memmove (y, &y3, sizeof (y3)); + memmove (y, (char *) &y3, sizeof (y3)); + memmove (x, w, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + memmove (x, (void *) y, sizeof (y)); + memmove (x, (char *) y1, sizeof (y2)); + memmove (x, y, sizeof (y) + 0); + memmove (x, y1, 0 + sizeof (y2)); + memmove (x, (void *) &c, sizeof (&c)); + memmove (x, (signed char *) &c, sizeof (&c)); + memmove (x, &c, sizeof (&c) + 0); + memmove (x, &c, 0 + sizeof (&c)); +} + +void +f4 (char *x, char **y, int z, char w[64]) +{ + const char *s1 = "foobarbaz"; + const char *s2 = "abcde12345678"; + strncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + strncat (x, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + stpncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + + strncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + strncat (w, s2, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + stpncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + + /* These are correct, no warning. */ + const char s3[] = "foobarbaz"; + const char s4[] = "abcde12345678"; + strncpy (x, s3, sizeof (s3)); + strncat (x, s4, sizeof (s4)); + stpncpy (x, s3, sizeof (s3)); +} + +/* { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" } */ diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C index c57096cc063..6cb39809d6c 100644 --- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C +++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C @@ -14,6 +14,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t); extern int memcmp (const void *, const void *, size_t); extern char *strncpy (char *__restrict, const char *__restrict, size_t); extern char *strncat (char *__restrict, const char *__restrict, size_t); +extern char *stpncpy (char *__restrict, const char *__restrict, size_t); extern char *strndup (const char *, size_t); extern int strncmp (const char *, const char *, size_t); extern int strncasecmp (const char *, const char *, size_t); @@ -56,6 +57,13 @@ strncat (char *dest, const char *src, size_t len) { return __builtin___strncat_chk (dest, src, len, bos (dest)); } + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +stpncpy (char *__restrict dest, const char *__restrict src, size_t len) +{ + return __builtin___stpncpy_chk (dest, src, len, bos (dest)); +} #endif } @@ -127,23 +135,23 @@ f1 (void *x, int z) memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } - z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - - z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } - z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } + z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } + z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } // These are correct, no warning. memset (&a, 0, sizeof a); @@ -331,23 +339,23 @@ f2 (void *x, int z) memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } - z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - - z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } - z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } + z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } + z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } // These are correct, no warning. memset (&b, 0, sizeof b); @@ -519,17 +527,17 @@ f3 (void *x, char *y, int z, X w) memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } - z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } + z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } - z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } - z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } + z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } // These are correct, no warning. memset (y, 0, sizeof (*y)); @@ -673,23 +681,29 @@ f3 (void *x, char *y, int z, X w) } int -f4 (char *x, char **y, int z) +f4 (char *x, char **y, int z, char w[64]) { const char *s1 = "foobarbaz"; const char *s2 = "abcde12345678"; strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + stpncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + + strncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + strncat (w, s2, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + stpncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } // These are correct, no warning. const char s3[] = "foobarbaz"; const char s4[] = "abcde12345678"; strncpy (x, s3, sizeof (s3)); strncat (x, s4, sizeof (s4)); + stpncpy (x, s3, sizeof (s3)); y[1] = strndup (s3, sizeof (s3)); z += strncmp (s3, s4, sizeof (s3)); z += strncmp (s3, s4, sizeof (s4)); diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C index d5a29d8f582..9e2805d2b74 100644 --- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C +++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C @@ -14,6 +14,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t); extern int memcmp (const void *, const void *, size_t); extern char *strncpy (char *__restrict, const char *__restrict, size_t); extern char *strncat (char *__restrict, const char *__restrict, size_t); +extern char *stpncpy (char *__restrict, const char *__restrict, size_t); extern char *strndup (const char *, size_t); extern int strncmp (const char *, const char *, size_t); extern int strncasecmp (const char *, const char *, size_t); @@ -56,6 +57,13 @@ strncat (char *dest, const char *src, size_t len) { return __builtin___strncat_chk (dest, src, len, bos (dest)); } + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +stpncpy (char *__restrict dest, const char *__restrict src, size_t len) +{ + return __builtin___stpncpy_chk (dest, src, len, bos (dest)); +} #endif } @@ -128,23 +136,23 @@ f1 (void *x, int z) memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } - z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - - z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } - z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } + z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } + z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } // These are correct, no warning. memset (&a, 0, sizeof a); @@ -333,23 +341,23 @@ f2 (void *x, int z) memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } - z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } - z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } - - z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } - z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } - z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } + z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } + z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } + + z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } + z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } + z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } + z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } // These are correct, no warning. memset (&b, 0, sizeof b); @@ -522,17 +530,17 @@ f3 (void *x, char *y, int z, X w) memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } - z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } - z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" } + z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } + z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" } - z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } - z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" } + z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } + z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" } // These are correct, no warning. memset (y, 0, sizeof (*y)); @@ -677,23 +685,29 @@ f3 (void *x, char *y, int z, X w) template <int N> int -f4 (char *x, char **y, int z) +f4 (char *x, char **y, int z, char w[64]) { const char *s1 = "foobarbaz"; const char *s2 = "abcde12345678"; strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + stpncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } - z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } - z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } + z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } + + strncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + strncat (w, s2, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } + stpncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } // These are correct, no warning. const char s3[] = "foobarbaz"; const char s4[] = "abcde12345678"; strncpy (x, s3, sizeof (s3)); strncat (x, s4, sizeof (s4)); + stpncpy (x, s3, sizeof (s3)); y[1] = strndup (s3, sizeof (s3)); z += strncmp (s3, s4, sizeof (s3)); z += strncmp (s3, s4, sizeof (s4)); @@ -704,12 +718,12 @@ f4 (char *x, char **y, int z) } int -f (void *x, char *y, int z, X w, char **u) +f (void *x, char *y, int z, X w, char **u, char v[64]) { z += f1<0> (x, z); z += f2<0> (x, z); z += f3<0> (x, y, z, w); - z += f4<0> (y, u, z); + z += f4<0> (y, u, z, v); return z; } diff --git a/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c new file mode 100644 index 00000000000..b683be7ceff --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c @@ -0,0 +1,456 @@ +/* Test -Wsizeof-pointer-memaccess warnings. */ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +typedef __SIZE_TYPE__ size_t; +extern void bzero (void *, size_t); +extern void bcopy (void *, const void *, size_t); +extern int bcmp (const void *, const void *, size_t); + +struct A { short a, b; int c, d; long e, f; }; +typedef struct A TA; +typedef struct A *PA; +typedef TA *PTA; +struct B {}; +typedef struct B TB; +typedef struct B *PB; +typedef TB *PTB; +typedef int X[3][3][3]; + +int +f1 (void *x, int z) +{ + struct A a, *pa1 = &a; + TA *pa2 = &a; + PA pa3 = &a; + PTA pa4 = &a; + bzero (&a, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + bzero (pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pa2, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pa4, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bzero (pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bzero (pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bzero (pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + bcopy (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + bcopy (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bcopy (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bcopy (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bcopy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + bcopy (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + bcopy (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + bcopy (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + bcopy (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + bcopy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + z += bcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */ + z += bcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + + z += bcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += bcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + + /* These are correct, no warning. */ + bzero (&a, sizeof a); + bzero (&a, sizeof (a)); + bzero (&a, sizeof (struct A)); + bzero (&a, sizeof (const struct A)); + bzero (&a, sizeof (volatile struct A)); + bzero (&a, sizeof (volatile const struct A)); + bzero (&a, sizeof (TA)); + bzero (&a, sizeof (__typeof (*&a))); + bzero (pa1, sizeof (*pa1)); + bzero (pa2, sizeof (*pa3)); + bzero (pa3, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + bzero ((void *) &a, sizeof (&a)); + bzero ((char *) &a, sizeof (&a)); + bzero (&a, sizeof (&a) + 0); + bzero (&a, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + bcopy (x, &a, sizeof a); + bcopy (x, &a, sizeof (a)); + bcopy (x, &a, sizeof (struct A)); + bcopy (x, &a, sizeof (const struct A)); + bcopy (x, &a, sizeof (volatile struct A)); + bcopy (x, &a, sizeof (volatile const struct A)); + bcopy (x, &a, sizeof (TA)); + bcopy (x, &a, sizeof (__typeof (*&a))); + bcopy (x, pa1, sizeof (*pa1)); + bcopy (x, pa2, sizeof (*pa3)); + bcopy (x, pa3, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + bcopy (x, (void *) &a, sizeof (&a)); + bcopy (x, (char *) &a, sizeof (&a)); + bcopy (x, &a, sizeof (&a) + 0); + bcopy (x, &a, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + bcopy (&a, x, sizeof a); + bcopy (&a, x, sizeof (a)); + bcopy (&a, x, sizeof (struct A)); + bcopy (&a, x, sizeof (const struct A)); + bcopy (&a, x, sizeof (volatile struct A)); + bcopy (&a, x, sizeof (volatile const struct A)); + bcopy (&a, x, sizeof (TA)); + bcopy (&a, x, sizeof (__typeof (*&a))); + bcopy (pa1, x, sizeof (*pa1)); + bcopy (pa2, x, sizeof (*pa3)); + bcopy (pa3, x, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + bcopy ((void *) &a, x, sizeof (&a)); + bcopy ((char *) &a, x, sizeof (&a)); + bcopy (&a, x, sizeof (&a) + 0); + bcopy (&a, x, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + z += bcmp (&a, x, sizeof a); + z += bcmp (&a, x, sizeof (a)); + z += bcmp (&a, x, sizeof (struct A)); + z += bcmp (&a, x, sizeof (const struct A)); + z += bcmp (&a, x, sizeof (volatile struct A)); + z += bcmp (&a, x, sizeof (volatile const struct A)); + z += bcmp (&a, x, sizeof (TA)); + z += bcmp (&a, x, sizeof (__typeof (*&a))); + z += bcmp (pa1, x, sizeof (*pa1)); + z += bcmp (pa2, x, sizeof (*pa3)); + z += bcmp (pa3, x, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + z += bcmp ((void *) &a, x, sizeof (&a)); + z += bcmp ((char *) &a, x, sizeof (&a)); + z += bcmp (&a, x, sizeof (&a) + 0); + z += bcmp (&a, x, 0 + sizeof (&a)); + + /* These are correct, no warning. */ + z += bcmp (x, &a, sizeof a); + z += bcmp (x, &a, sizeof (a)); + z += bcmp (x, &a, sizeof (struct A)); + z += bcmp (x, &a, sizeof (const struct A)); + z += bcmp (x, &a, sizeof (volatile struct A)); + z += bcmp (x, &a, sizeof (volatile const struct A)); + z += bcmp (x, &a, sizeof (TA)); + z += bcmp (x, &a, sizeof (__typeof (*&a))); + z += bcmp (x, pa1, sizeof (*pa1)); + z += bcmp (x, pa2, sizeof (*pa3)); + z += bcmp (x, pa3, sizeof (__typeof (*pa3))); + /* These are probably broken, but obfuscated, no warning. */ + z += bcmp (x, (void *) &a, sizeof (&a)); + z += bcmp (x, (char *) &a, sizeof (&a)); + z += bcmp (x, &a, sizeof (&a) + 0); + z += bcmp (x, &a, 0 + sizeof (&a)); + + return z; +} + +int +f2 (void *x, int z) +{ + struct B b, *pb1 = &b; + TB *pb2 = &b; + PB pb3 = &b; + PTB pb4 = &b; + bzero (&b, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + bzero (pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pb2, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pb4, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bzero (pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bzero (pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bzero (pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bzero (pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + bcopy (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + bcopy (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + bcopy (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bcopy (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bcopy (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + bcopy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ + + bcopy (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + bcopy (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + bcopy (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + bcopy (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + bcopy (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + bcopy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + + z += bcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */ + z += bcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += bcmp (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + + z += bcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += bcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += bcmp (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += bcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + + /* These are correct, no warning. */ + bzero (&b, sizeof b); + bzero (&b, sizeof (b)); + bzero (&b, sizeof (struct B)); + bzero (&b, sizeof (const struct B)); + bzero (&b, sizeof (volatile struct B)); + bzero (&b, sizeof (volatile const struct B)); + bzero (&b, sizeof (TB)); + bzero (&b, sizeof (__typeof (*&b))); + bzero (pb1, sizeof (*pb1)); + bzero (pb2, sizeof (*pb3)); + bzero (pb3, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + bzero ((void *) &b, sizeof (&b)); + bzero ((char *) &b, sizeof (&b)); + bzero (&b, sizeof (&b) + 0); + bzero (&b, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + bcopy (x, &b, sizeof b); + bcopy (x, &b, sizeof (b)); + bcopy (x, &b, sizeof (struct B)); + bcopy (x, &b, sizeof (const struct B)); + bcopy (x, &b, sizeof (volatile struct B)); + bcopy (x, &b, sizeof (volatile const struct B)); + bcopy (x, &b, sizeof (TB)); + bcopy (x, &b, sizeof (__typeof (*&b))); + bcopy (x, pb1, sizeof (*pb1)); + bcopy (x, pb2, sizeof (*pb3)); + bcopy (x, pb3, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + bcopy (x, (void *) &b, sizeof (&b)); + bcopy (x, (char *) &b, sizeof (&b)); + bcopy (x, &b, sizeof (&b) + 0); + bcopy (x, &b, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + bcopy (&b, x, sizeof b); + bcopy (&b, x, sizeof (b)); + bcopy (&b, x, sizeof (struct B)); + bcopy (&b, x, sizeof (const struct B)); + bcopy (&b, x, sizeof (volatile struct B)); + bcopy (&b, x, sizeof (volatile const struct B)); + bcopy (&b, x, sizeof (TB)); + bcopy (&b, x, sizeof (__typeof (*&b))); + bcopy (pb1, x, sizeof (*pb1)); + bcopy (pb2, x, sizeof (*pb3)); + bcopy (pb3, x, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + bcopy ((void *) &b, x, sizeof (&b)); + bcopy ((char *) &b, x, sizeof (&b)); + bcopy (&b, x, sizeof (&b) + 0); + bcopy (&b, x, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + z += bcmp (&b, x, sizeof b); + z += bcmp (&b, x, sizeof (b)); + z += bcmp (&b, x, sizeof (struct B)); + z += bcmp (&b, x, sizeof (const struct B)); + z += bcmp (&b, x, sizeof (volatile struct B)); + z += bcmp (&b, x, sizeof (volatile const struct B)); + z += bcmp (&b, x, sizeof (TB)); + z += bcmp (&b, x, sizeof (__typeof (*&b))); + z += bcmp (pb1, x, sizeof (*pb1)); + z += bcmp (pb2, x, sizeof (*pb3)); + z += bcmp (pb3, x, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + z += bcmp ((void *) &b, x, sizeof (&b)); + z += bcmp ((char *) &b, x, sizeof (&b)); + z += bcmp (&b, x, sizeof (&b) + 0); + z += bcmp (&b, x, 0 + sizeof (&b)); + + /* These are correct, no warning. */ + z += bcmp (x, &b, sizeof b); + z += bcmp (x, &b, sizeof (b)); + z += bcmp (x, &b, sizeof (struct B)); + z += bcmp (x, &b, sizeof (const struct B)); + z += bcmp (x, &b, sizeof (volatile struct B)); + z += bcmp (x, &b, sizeof (volatile const struct B)); + z += bcmp (x, &b, sizeof (TB)); + z += bcmp (x, &b, sizeof (__typeof (*&b))); + z += bcmp (x, pb1, sizeof (*pb1)); + z += bcmp (x, pb2, sizeof (*pb3)); + z += bcmp (x, pb3, sizeof (__typeof (*pb3))); + /* These are probably broken, but obfuscated, no warning. */ + z += bcmp (x, (void *) &b, sizeof (&b)); + z += bcmp (x, (char *) &b, sizeof (&b)); + z += bcmp (x, &b, sizeof (&b) + 0); + z += bcmp (x, &b, 0 + sizeof (&b)); + + return z; +} + +int +f3 (void *x, char *y, int z, X w) +{ + unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16); + char buf1[7]; + signed char buf2[z + 32]; + long buf3[17]; + int *buf4[9]; + signed char *y2 = buf2; + char c; + char *y3; + bzero (y, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + bzero (y1, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + bzero (y2, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + bzero (&c, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + bzero (w, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + + bcopy (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + bcopy (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + bcopy (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + bcopy (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ + bcopy (x, w, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + + bcopy (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + bcopy (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + bcopy (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + bcopy (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ + bcopy (w, x, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + + z += bcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += bcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += bcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += bcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */ + z += bcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + + z += bcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += bcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += bcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += bcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += bcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + + /* These are correct, no warning. */ + bzero (y, sizeof (*y)); + bzero (y1, sizeof (*y2)); + bzero (buf1, sizeof buf1); + bzero (buf3, sizeof (buf3)); + bzero (&buf3[0], sizeof (buf3)); + bzero (&buf4[0], sizeof (buf4)); + bzero (w, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + bzero ((void *) y, sizeof (y)); + bzero ((char *) y1, sizeof (y2)); + bzero (y, sizeof (y) + 0); + bzero (y1, 0 + sizeof (y2)); + bzero ((void *) &c, sizeof (&c)); + bzero ((signed char *) &c, sizeof (&c)); + bzero (&c, sizeof (&c) + 0); + bzero (&c, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + bcopy (x, y, sizeof (*y)); + bcopy (x, y1, sizeof (*y2)); + bcopy (x, buf1, sizeof buf1); + bcopy (x, buf3, sizeof (buf3)); + bcopy (x, &buf3[0], sizeof (buf3)); + bcopy (x, &buf4[0], sizeof (buf4)); + bcopy (y, &y3, sizeof (y3)); + bcopy (y, (char *) &y3, sizeof (y3)); + bcopy (x, w, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + bcopy (x, (void *) y, sizeof (y)); + bcopy (x, (char *) y1, sizeof (y2)); + bcopy (x, y, sizeof (y) + 0); + bcopy (x, y1, 0 + sizeof (y2)); + bcopy (x, (void *) &c, sizeof (&c)); + bcopy (x, (signed char *) &c, sizeof (&c)); + bcopy (x, &c, sizeof (&c) + 0); + bcopy (x, &c, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + bcopy (y, x, sizeof (*y)); + bcopy (y1, x, sizeof (*y2)); + bcopy (buf1, x, sizeof buf1); + bcopy (buf3, x, sizeof (buf3)); + bcopy (&buf3[0], x, sizeof (buf3)); + bcopy (&buf4[0], x, sizeof (buf4)); + bcopy (&y3, y, sizeof (y3)); + bcopy ((char *) &y3, y, sizeof (y3)); + bcopy (w, x, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + bcopy ((void *) y, x, sizeof (y)); + bcopy ((char *) y1, x, sizeof (y2)); + bcopy (y, x, sizeof (y) + 0); + bcopy (y1, x, 0 + sizeof (y2)); + bcopy ((void *) &c, x, sizeof (&c)); + bcopy ((signed char *) &c, x, sizeof (&c)); + bcopy (&c, x, sizeof (&c) + 0); + bcopy (&c, x, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + z += bcmp (y, x, sizeof (*y)); + z += bcmp (y1, x, sizeof (*y2)); + z += bcmp (buf1, x, sizeof buf1); + z += bcmp (buf3, x, sizeof (buf3)); + z += bcmp (&buf3[0], x, sizeof (buf3)); + z += bcmp (&buf4[0], x, sizeof (buf4)); + z += bcmp (&y3, y, sizeof (y3)); + z += bcmp ((char *) &y3, y, sizeof (y3)); + z += bcmp (w, x, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + z += bcmp ((void *) y, x, sizeof (y)); + z += bcmp ((char *) y1, x, sizeof (y2)); + z += bcmp (y, x, sizeof (y) + 0); + z += bcmp (y1, x, 0 + sizeof (y2)); + z += bcmp ((void *) &c, x, sizeof (&c)); + z += bcmp ((signed char *) &c, x, sizeof (&c)); + z += bcmp (&c, x, sizeof (&c) + 0); + z += bcmp (&c, x, 0 + sizeof (&c)); + + /* These are correct, no warning. */ + z += bcmp (x, y, sizeof (*y)); + z += bcmp (x, y1, sizeof (*y2)); + z += bcmp (x, buf1, sizeof buf1); + z += bcmp (x, buf3, sizeof (buf3)); + z += bcmp (x, &buf3[0], sizeof (buf3)); + z += bcmp (x, &buf4[0], sizeof (buf4)); + z += bcmp (y, &y3, sizeof (y3)); + z += bcmp (y, (char *) &y3, sizeof (y3)); + z += bcmp (x, w, sizeof (X)); + /* These are probably broken, but obfuscated, no warning. */ + z += bcmp (x, (void *) y, sizeof (y)); + z += bcmp (x, (char *) y1, sizeof (y2)); + z += bcmp (x, y, sizeof (y) + 0); + z += bcmp (x, y1, 0 + sizeof (y2)); + z += bcmp (x, (void *) &c, sizeof (&c)); + z += bcmp (x, (signed char *) &c, sizeof (&c)); + z += bcmp (x, &c, sizeof (&c) + 0); + z += bcmp (x, &c, 0 + sizeof (&c)); + + return z; +} diff --git a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c index 3897518de63..8d01bc616a7 100644 --- a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c +++ b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c @@ -12,6 +12,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t); extern int memcmp (const void *, const void *, size_t); extern char *strncpy (char *__restrict, const char *__restrict, size_t); extern char *strncat (char *__restrict, const char *__restrict, size_t); +extern char *stpncpy (char *__restrict, const char *__restrict, size_t); extern char *strndup (const char *, size_t); extern int strncmp (const char *, const char *, size_t); extern int strncasecmp (const char *, const char *, size_t); @@ -54,6 +55,13 @@ strncat (char *dest, const char *src, size_t len) { return __builtin___strncat_chk (dest, src, len, bos (dest)); } + +__attribute__((__always_inline__, __gnu_inline__, __artificial__)) +extern inline char * +stpncpy (char *__restrict dest, const char *__restrict src, size_t len) +{ + return __builtin___stpncpy_chk (dest, src, len, bos (dest)); +} #endif struct A { short a, b; int c, d; long e, f; }; @@ -123,23 +131,23 @@ f1 (void *x, int z) memmove (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ - z += memcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ - - z += memcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ - z += memcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */ + z += memcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + + z += memcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += memcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ /* These are correct, no warning. */ memset (&a, 0, sizeof a); @@ -327,23 +335,23 @@ f2 (void *x, int z) memmove (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ - z += memcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ - z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */ - - z += memcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ - z += memcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ - z += memcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */ + z += memcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ + z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */ + + z += memcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += memcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ + z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ + z += memcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */ /* These are correct, no warning. */ memset (&b, 0, sizeof b); @@ -515,17 +523,17 @@ f3 (void *x, char *y, int z, X w) memmove (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ memmove (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ - z += memcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ - z += memcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ - z += memcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ - z += memcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */ - z += memcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */ + z += memcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += memcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += memcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += memcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */ + z += memcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */ - z += memcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ - z += memcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ - z += memcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ - z += memcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */ - z += memcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */ + z += memcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += memcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += memcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += memcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */ + z += memcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */ /* These are correct, no warning. */ memset (y, 0, sizeof (*y)); @@ -669,23 +677,29 @@ f3 (void *x, char *y, int z, X w) } int -f4 (char *x, char **y, int z) +f4 (char *x, char **y, int z, char w[64]) { const char *s1 = "foobarbaz"; const char *s2 = "abcde12345678"; strncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ strncat (x, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + stpncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ y[0] = strndup (s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ - z += strncmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ - z += strncmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ - z += strncasecmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ - z += strncasecmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */ + z += strncmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += strncmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + z += strncasecmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */ + z += strncasecmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */ + + strncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + strncat (w, s2, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ + stpncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */ /* These are correct, no warning. */ const char s3[] = "foobarbaz"; const char s4[] = "abcde12345678"; strncpy (x, s3, sizeof (s3)); strncat (x, s4, sizeof (s4)); + stpncpy (x, s3, sizeof (s3)); y[1] = strndup (s3, sizeof (s3)); z += strncmp (s3, s4, sizeof (s3)); z += strncmp (s3, s4, sizeof (s4)); |