summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-12 18:23:03 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-12 18:23:03 +0000
commit57f872a2a1689ced0b7340178e6984393d07662e (patch)
tree53a2b873d7fe4f0c44a653a6e7c37c843b92ade2
parent25d34a34470da2747013743e6a962f023d7a5868 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/c-family/c-common.c168
-rw-r--r--gcc/c-family/c-common.h4
-rw-r--r--gcc/c/ChangeLog13
-rw-r--r--gcc/c/c-parser.c71
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/semantics.c28
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c161
-rw-r--r--gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c482
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C112
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C116
-rw-r--r--gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c456
-rw-r--r--gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c112
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));