invoke.texi (-Wsizeof-pointer-memaccess): Document.

* doc/invoke.texi (-Wsizeof-pointer-memaccess): Document.
c/
	* c-tree.h (c_last_sizeof_arg): Declare.
	* c-parser.c (struct c_tree_loc_pair): New type.
	(c_parser_expr_list): Add sizeof_arg argument.  Fill it in if
	non-NULL.
	(c_parser_attributes, c_parser_objc_keywordexpr): Adjust callers.
	(c_parser_postfix_expression_after_primary): Likewise.  Call
	sizeof_pointer_memaccess_warning if needed.
	(sizeof_ptr_memacc_comptypes): New function.
	* c-typeck.c (c_last_sizeof_arg): New global variable.
	(c_expr_sizeof_expr, c_expr_sizeof_type): Initialize it.
cp/
	* cp-tree.def (SIZEOF_EXPR): Move to c-common.def.
c-family/
	* c-common.c (sizeof_pointer_memaccess_warning): New function.
	* c.opt (-Wsizeof-pointer-memaccess): Add new option.
	* c-opts.c (c_common_handle_option): Enable it for -Wall.
	* c-common.h (sizeof_pointer_memaccess_warning): Add prototype.
	* c-common.def (SIZEOF_EXPR): Moved here from cp-tree.def.
fortran/
	* array.c (gfc_match_array_ref): Fix up memset arguments.
testsuite/
	* gcc.dg/torture/Wsizeof-pointer-memaccess1.c: New test.

From-SVN: r190467
This commit is contained in:
Jakub Jelinek 2012-08-17 09:17:56 +02:00 committed by Jakub Jelinek
parent 138f5acd18
commit 1a4049e7c5
18 changed files with 983 additions and 27 deletions

View File

@ -1,3 +1,7 @@
2012-08-17 Jakub Jelinek <jakub@redhat.com>
* doc/invoke.texi (-Wsizeof-pointer-memaccess): Document.
2012-08-16 Sandra Loosemore <sandra@codesourcery.com>
* config/mips/mips-dsp.md (mips_dpau_h_qbl, mips_dpau_h_qbr)

View File

@ -1,3 +1,11 @@
2012-08-17 Jakub Jelinek <jakub@redhat.com>
* c-common.c (sizeof_pointer_memaccess_warning): New function.
* c.opt (-Wsizeof-pointer-memaccess): Add new option.
* c-opts.c (c_common_handle_option): Enable it for -Wall.
* c-common.h (sizeof_pointer_memaccess_warning): Add prototype.
* c-common.def (SIZEOF_EXPR): Moved here from cp-tree.def.
2012-08-10 Richard Guenther <rguenther@suse.de>
* c-pretty-print.c (pp_c_expression): Handle anonymous SSA names.

View File

@ -1841,6 +1841,149 @@ strict_aliasing_warning (tree otype, tree type, tree expr)
return false;
}
/* Warn about memset (&a, 0, sizeof (&a)); and similar mistakes with
sizeof as last operand of certain builtins. */
void
sizeof_pointer_memaccess_warning (location_t 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;
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:
case BUILT_IN_STRNCPY:
case BUILT_IN_STRNCAT:
strop = true;
/* FALLTHRU */
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMMOVE:
case BUILT_IN_MEMCMP:
if (VEC_length (tree, params) < 3)
return;
src = VEC_index (tree, params, 1);
dest = VEC_index (tree, params, 0);
break;
case BUILT_IN_MEMSET:
if (VEC_length (tree, params) < 3)
return;
dest = VEC_index (tree, params, 0);
break;
case BUILT_IN_STRNDUP:
src = VEC_index (tree, params, 0);
strop = true;
break;
default:
break;
}
if (dest
&& (tem = tree_strip_nop_conversions (dest))
&& POINTER_TYPE_P (TREE_TYPE (tem))
&& comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
return;
if (src
&& (tem = tree_strip_nop_conversions (src))
&& POINTER_TYPE_P (TREE_TYPE (tem))
&& comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
return;
if (dest)
{
if (!TYPE_P (sizeof_arg)
&& operand_equal_p (dest, sizeof_arg, 0)
&& comp_types (TREE_TYPE (dest), type))
{
if (TREE_CODE (sizeof_arg) == 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 "
"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 destination; 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 destination; 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 destination; expected %qT "
"or an explicit length", callee, TREE_TYPE (dest),
TREE_TYPE (TREE_TYPE (dest)));
return;
}
}
if (src)
{
if (!TYPE_P (sizeof_arg)
&& operand_equal_p (src, sizeof_arg, 0)
&& comp_types (TREE_TYPE (src), type))
{
if (TREE_CODE (sizeof_arg) == 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 "
"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 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 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 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
of `main'. */

View File

@ -2,7 +2,7 @@
additional tree codes used in the GNU C compiler (see tree.def
for the standard codes).
Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
1999, 2000, 2001, 2004, 2005, 2007, 2009, 2010
1999, 2000, 2001, 2004, 2005, 2007, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Written by Benjamin Chelf <chelf@codesourcery.com>
@ -53,6 +53,10 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1)
number. */
DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
/* Represents a 'sizeof' expression during C++ template expansion,
or for the purpose of -Wsizeof-pointer-memaccess warning. */
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
/*
Local variables:
mode:c

View File

@ -1,6 +1,6 @@
/* Definitions for c-common.c.
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002,
2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@ -768,6 +768,9 @@ 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,
bool (*) (tree, tree));
extern void warnings_for_convert_and_check (tree, tree, tree);
extern tree convert_and_check (tree, tree);
extern void overflow_warning (location_t, tree);

View File

@ -1,6 +1,6 @@
/* C/ObjC/C++ command line option handling.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
2012 Free Software Foundation, Inc.
Contributed by Neil Booth.
This file is part of GCC.
@ -374,6 +374,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
warn_return_type = value;
warn_sequence_point = value; /* Was C only. */
warn_switch = value;
warn_sizeof_pointer_memaccess = value;
if (warn_strict_aliasing == -1)
set_Wstrict_aliasing (&global_options, value);
warn_address = value;

View File

@ -474,6 +474,9 @@ Wmissing-field-initializers
C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Warning EnabledBy(Wextra)
Warn about missing fields in struct initializers
Wsizeof-pointer-memaccess
C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning
Wsuggest-attribute=format
C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
Warn about functions which might be candidates for format attributes

View File

@ -1,3 +1,16 @@
2012-08-17 Jakub Jelinek <jakub@redhat.com>
* c-tree.h (c_last_sizeof_arg): Declare.
* c-parser.c (struct c_tree_loc_pair): New type.
(c_parser_expr_list): Add sizeof_arg argument. Fill it in if
non-NULL.
(c_parser_attributes, c_parser_objc_keywordexpr): Adjust callers.
(c_parser_postfix_expression_after_primary): Likewise. Call
sizeof_pointer_memaccess_warning if needed.
(sizeof_ptr_memacc_comptypes): New function.
* c-typeck.c (c_last_sizeof_arg): New global variable.
(c_expr_sizeof_expr, c_expr_sizeof_type): Initialize it.
2012-07-24 Uros Bizjak <ubizjak@gmail.com>
* c-lang.h (lang_decl): Add variable_size GTY option.

View File

@ -1111,6 +1111,12 @@ 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,
@ -1179,7 +1185,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) **);
VEC(tree,gc) **,
struct c_tree_loc_pair *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@ -3578,7 +3585,8 @@ c_parser_attributes (c_parser *parser)
{
tree tree_list;
c_parser_consume_token (parser);
expr_list = c_parser_expr_list (parser, false, true, NULL);
expr_list = c_parser_expr_list (parser, false, true,
NULL, NULL);
tree_list = build_tree_list_vec (expr_list);
attr_args = tree_cons (NULL_TREE, arg1, tree_list);
release_tree_vector (expr_list);
@ -3590,7 +3598,8 @@ c_parser_attributes (c_parser *parser)
attr_args = NULL_TREE;
else
{
expr_list = c_parser_expr_list (parser, false, true, NULL);
expr_list = c_parser_expr_list (parser, false, true,
NULL, NULL);
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
}
@ -6845,6 +6854,15 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
}
/* Callback function for sizeof_pointer_memaccess_warning to compare
types. */
static bool
sizeof_ptr_memacc_comptypes (tree type1, tree type2)
{
return comptypes (type1, type2) == 1;
}
/* Parse a postfix expression after the initial primary or compound
literal; that is, parse a series of postfix operators.
@ -6857,6 +6875,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
{
struct c_expr orig_expr;
tree ident, idx;
struct c_tree_loc_pair sizeof_arg;
VEC(tree,gc) *exprlist;
VEC(tree,gc) *origtypes;
while (true)
@ -6877,14 +6896,22 @@ 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;
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
exprlist = NULL;
else
exprlist = c_parser_expr_list (parser, true, false, &origtypes);
exprlist = c_parser_expr_list (parser, true, false, &origtypes,
&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,
expr.value, exprlist,
sizeof_arg.expr,
sizeof_ptr_memacc_comptypes);
/* FIXME diagnostics: Ideally we want the FUNCNAME, not the
"(" after the FUNCNAME, which is what we have now. */
expr.value = build_function_call_vec (op_loc, expr.value, exprlist,
@ -7045,12 +7072,14 @@ 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)
VEC(tree,gc) **p_orig_types,
struct c_tree_loc_pair *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;
ret = make_tree_vector ();
if (p_orig_types == NULL)
@ -7058,6 +7087,9 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
else
orig_types = make_tree_vector ();
if (sizeof_arg != NULL
&& c_parser_next_token_is_keyword (parser, RID_SIZEOF))
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);
@ -7070,6 +7102,11 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
{
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;
else
sizeof_arg_loc = UNKNOWN_LOCATION;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_read_conversion (loc, expr);
@ -7079,6 +7116,20 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
if (orig_types != NULL)
VEC_safe_push (tree, gc, orig_types, expr.original_type);
}
if (sizeof_arg != NULL)
{
if (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;
}
}
if (orig_types != NULL)
*p_orig_types = orig_types;
return ret;
@ -8157,7 +8208,8 @@ static tree
c_parser_objc_keywordexpr (c_parser *parser)
{
tree ret;
VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, NULL);
VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true,
NULL, NULL);
if (VEC_length (tree, expr_list) == 1)
{
/* Just return the expression, remove a level of

View File

@ -1,7 +1,7 @@
/* Definitions for C parsing and type checking.
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011,
2012 Free Software Foundation, Inc.
This file is part of GCC.
@ -573,6 +573,8 @@ extern int in_alignof;
extern int in_sizeof;
extern int in_typeof;
extern tree c_last_sizeof_arg;
extern struct c_switch *c_switch_stack;
extern tree c_objc_common_truthvalue_conversion (location_t, tree);

View File

@ -1,7 +1,7 @@
/* Build expressions with type checking for C compiler.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012 Free Software Foundation, Inc.
This file is part of GCC.
@ -67,6 +67,10 @@ int in_sizeof;
/* The level of nesting inside "typeof". */
int in_typeof;
/* The argument of last parsed sizeof expression, only to be tested
if expr.original_code == SIZEOF_EXPR. */
tree c_last_sizeof_arg;
/* Nonzero if we've already printed a "missing braces around initializer"
message within this initializer. */
static int missing_braces_mentioned;
@ -2603,7 +2607,8 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
tree folded_expr = c_fully_fold (expr.value, require_constant_value,
&expr_const_operands);
ret.value = c_sizeof (loc, TREE_TYPE (folded_expr));
ret.original_code = ERROR_MARK;
c_last_sizeof_arg = expr.value;
ret.original_code = SIZEOF_EXPR;
ret.original_type = NULL;
if (c_vla_type_p (TREE_TYPE (folded_expr)))
{
@ -2631,7 +2636,8 @@ c_expr_sizeof_type (location_t loc, struct c_type_name *t)
bool type_expr_const = true;
type = groktypename (t, &type_expr, &type_expr_const);
ret.value = c_sizeof (loc, type);
ret.original_code = ERROR_MARK;
c_last_sizeof_arg = type;
ret.original_code = SIZEOF_EXPR;
ret.original_type = NULL;
if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST)
&& c_vla_type_p (type))

View File

@ -1,3 +1,7 @@
2012-08-17 Jakub Jelinek <jakub@redhat.com>
* cp-tree.def (SIZEOF_EXPR): Move to c-common.def.
2012-08-14 Diego Novillo <dnovillo@google.com>
Merge from cxx-conversion branch. Re-write VEC in C++.

View File

@ -2,7 +2,7 @@
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998, 2003, 2004, 2005,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010, 2011
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2010, 2011, 2012
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@ -333,9 +333,6 @@ DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0)
/* Represents an 'offsetof' expression during template expansion. */
DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1)
/* Represents a 'sizeof' expression during template expansion. */
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
/* Represents the -> operator during template expansion. */
DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1)

View File

@ -263,9 +263,9 @@ Objective-C and Objective-C++ Dialects}.
-Wpointer-arith -Wno-pointer-to-int-cast @gol
-Wredundant-decls @gol
-Wreturn-type -Wsequence-point -Wshadow @gol
-Wsign-compare -Wsign-conversion -Wstack-protector @gol
-Wstack-usage=@var{len} -Wstrict-aliasing -Wstrict-aliasing=n @gol
-Wstrict-overflow -Wstrict-overflow=@var{n} @gol
-Wsign-compare -Wsign-conversion -Wsizeof-pointer-memaccess @gol
-Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
-Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
-Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]} @gol
-Wmissing-format-attribute @gol
-Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol
@ -4327,6 +4327,16 @@ value, like assigning a signed integer expression to an unsigned
integer variable. An explicit cast silences the warning. In C, this
option is enabled also by @option{-Wconversion}.
@item -Wsizeof-pointer-memaccess
@opindex Wsizeof-pointer-memaccess
@opindex Wno-sizeof-pointer-memaccess
Warn for suspicious length parameters to certain string and memory built-in
functions if the argument uses @code{sizeof}. This warning warns e.g.@:
about @code{memset (ptr, 0, sizeof (ptr));} if @code{ptr} is not an array,
but a pointer, and suggests a possible fix, or about
@code{memcpy (&foo, ptr, sizeof (&foo));}. This warning is enabled by
@option{-Wall}.
@item -Waddress
@opindex Waddress
@opindex Wno-address

View File

@ -1,3 +1,7 @@
2012-08-17 Jakub Jelinek <jakub@redhat.com>
* array.c (gfc_match_array_ref): Fix up memset arguments.
2012-08-16 Diego Novillo <dnovillo@google.com>
Revert

View File

@ -1,6 +1,6 @@
/* Array things
Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012 Free Software Foundation, Inc.
Contributed by Andy Vaught
This file is part of GCC.
@ -159,7 +159,7 @@ gfc_match_array_ref (gfc_array_ref *ar, gfc_array_spec *as, int init,
match m;
bool matched_bracket = false;
memset (ar, '\0', sizeof (ar));
memset (ar, '\0', sizeof (*ar));
ar->where = gfc_current_locus;
ar->as = as;

View File

@ -1,3 +1,7 @@
2012-08-17 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/torture/Wsizeof-pointer-memaccess1.c: New test.
2012-08-16 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54236

View File

@ -0,0 +1,698 @@
/* Test -Wsizeof-pointer-memaccess warnings. */
/* { dg-do compile } */
/* { dg-options "-Wall" } */
/* Test just twice, once with -O0 non-fortified, once with -O2 fortified. */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
typedef __SIZE_TYPE__ size_t;
extern void *memset (void *, int, size_t);
extern void *memcpy (void *__restrict, const void *__restrict, size_t);
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 *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
#ifdef __OPTIMIZE__
# define bos(ptr) __builtin_object_size (ptr, 1)
# define bos0(ptr) __builtin_object_size (ptr, 0)
__attribute__((__always_inline__, __gnu_inline__, __artificial__))
extern inline void *
memset (void *dest, int c, size_t len)
{
return __builtin___memset_chk (dest, c, len, bos0 (dest));
}
__attribute__((__always_inline__, __gnu_inline__, __artificial__))
extern inline void *
memcpy (void *__restrict dest, const void *__restrict src, size_t len)
{
return __builtin___memcpy_chk (dest, src, len, bos0 (dest));
}
__attribute__((__always_inline__, __gnu_inline__, __artificial__))
extern inline void *
memmove (void *dest, const void *src, size_t len)
{
return __builtin___memmove_chk (dest, src, len, bos0 (dest));
}
__attribute__((__always_inline__, __gnu_inline__, __artificial__))
extern inline char *
strncpy (char *__restrict dest, const char *__restrict src, size_t len)
{
return __builtin___strncpy_chk (dest, src, len, bos (dest));
}
__attribute__((__always_inline__, __gnu_inline__, __artificial__))
extern inline char *
strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
#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];
int
f1 (void *x, int z)
{
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" } */
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" } */
/* 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));
/* These are correct, no warning. */
z += memcmp (&a, x, sizeof a);
z += memcmp (&a, x, sizeof (a));
z += memcmp (&a, x, sizeof (struct A));
z += memcmp (&a, x, sizeof (const struct A));
z += memcmp (&a, x, sizeof (volatile struct A));
z += memcmp (&a, x, sizeof (volatile const struct A));
z += memcmp (&a, x, sizeof (TA));
z += memcmp (&a, x, sizeof (__typeof (*&a)));
z += memcmp (pa1, x, sizeof (*pa1));
z += memcmp (pa2, x, sizeof (*pa3));
z += memcmp (pa3, x, sizeof (__typeof (*pa3)));
/* These are probably broken, but obfuscated, no warning. */
z += memcmp ((void *) &a, x, sizeof (&a));
z += memcmp ((char *) &a, x, sizeof (&a));
z += memcmp (&a, x, sizeof (&a) + 0);
z += memcmp (&a, x, 0 + sizeof (&a));
/* These are correct, no warning. */
z += memcmp (x, &a, sizeof a);
z += memcmp (x, &a, sizeof (a));
z += memcmp (x, &a, sizeof (struct A));
z += memcmp (x, &a, sizeof (const struct A));
z += memcmp (x, &a, sizeof (volatile struct A));
z += memcmp (x, &a, sizeof (volatile const struct A));
z += memcmp (x, &a, sizeof (TA));
z += memcmp (x, &a, sizeof (__typeof (*&a)));
z += memcmp (x, pa1, sizeof (*pa1));
z += memcmp (x, pa2, sizeof (*pa3));
z += memcmp (x, pa3, sizeof (__typeof (*pa3)));
/* These are probably broken, but obfuscated, no warning. */
z += memcmp (x, (void *) &a, sizeof (&a));
z += memcmp (x, (char *) &a, sizeof (&a));
z += memcmp (x, &a, sizeof (&a) + 0);
z += memcmp (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;
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" } */
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" } */
/* 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));
/* These are correct, no warning. */
z += memcmp (&b, x, sizeof b);
z += memcmp (&b, x, sizeof (b));
z += memcmp (&b, x, sizeof (struct B));
z += memcmp (&b, x, sizeof (const struct B));
z += memcmp (&b, x, sizeof (volatile struct B));
z += memcmp (&b, x, sizeof (volatile const struct B));
z += memcmp (&b, x, sizeof (TB));
z += memcmp (&b, x, sizeof (__typeof (*&b)));
z += memcmp (pb1, x, sizeof (*pb1));
z += memcmp (pb2, x, sizeof (*pb3));
z += memcmp (pb3, x, sizeof (__typeof (*pb3)));
/* These are probably broken, but obfuscated, no warning. */
z += memcmp ((void *) &b, x, sizeof (&b));
z += memcmp ((char *) &b, x, sizeof (&b));
z += memcmp (&b, x, sizeof (&b) + 0);
z += memcmp (&b, x, 0 + sizeof (&b));
/* These are correct, no warning. */
z += memcmp (x, &b, sizeof b);
z += memcmp (x, &b, sizeof (b));
z += memcmp (x, &b, sizeof (struct B));
z += memcmp (x, &b, sizeof (const struct B));
z += memcmp (x, &b, sizeof (volatile struct B));
z += memcmp (x, &b, sizeof (volatile const struct B));
z += memcmp (x, &b, sizeof (TB));
z += memcmp (x, &b, sizeof (__typeof (*&b)));
z += memcmp (x, pb1, sizeof (*pb1));
z += memcmp (x, pb2, sizeof (*pb3));
z += memcmp (x, pb3, sizeof (__typeof (*pb3)));
/* These are probably broken, but obfuscated, no warning. */
z += memcmp (x, (void *) &b, sizeof (&b));
z += memcmp (x, (char *) &b, sizeof (&b));
z += memcmp (x, &b, sizeof (&b) + 0);
z += memcmp (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;
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" } */
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 (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" } */
/* 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));
/* These are correct, no warning. */
z += memcmp (y, x, sizeof (*y));
z += memcmp (y1, x, sizeof (*y2));
z += memcmp (buf1, x, sizeof buf1);
z += memcmp (buf3, x, sizeof (buf3));
z += memcmp (&buf3[0], x, sizeof (buf3));
z += memcmp (&buf4[0], x, sizeof (buf4));
z += memcmp (&y3, y, sizeof (y3));
z += memcmp ((char *) &y3, y, sizeof (y3));
z += memcmp (w, x, sizeof (X));
/* These are probably broken, but obfuscated, no warning. */
z += memcmp ((void *) y, x, sizeof (y));
z += memcmp ((char *) y1, x, sizeof (y2));
z += memcmp (y, x, sizeof (y) + 0);
z += memcmp (y1, x, 0 + sizeof (y2));
z += memcmp ((void *) &c, x, sizeof (&c));
z += memcmp ((signed char *) &c, x, sizeof (&c));
z += memcmp (&c, x, sizeof (&c) + 0);
z += memcmp (&c, x, 0 + sizeof (&c));
/* These are correct, no warning. */
z += memcmp (x, y, sizeof (*y));
z += memcmp (x, y1, sizeof (*y2));
z += memcmp (x, buf1, sizeof buf1);
z += memcmp (x, buf3, sizeof (buf3));
z += memcmp (x, &buf3[0], sizeof (buf3));
z += memcmp (x, &buf4[0], sizeof (buf4));
z += memcmp (y, &y3, sizeof (y3));
z += memcmp (y, (char *) &y3, sizeof (y3));
z += memcmp (x, w, sizeof (X));
/* These are probably broken, but obfuscated, no warning. */
z += memcmp (x, (void *) y, sizeof (y));
z += memcmp (x, (char *) y1, sizeof (y2));
z += memcmp (x, y, sizeof (y) + 0);
z += memcmp (x, y1, 0 + sizeof (y2));
z += memcmp (x, (void *) &c, sizeof (&c));
z += memcmp (x, (signed char *) &c, sizeof (&c));
z += memcmp (x, &c, sizeof (&c) + 0);
z += memcmp (x, &c, 0 + sizeof (&c));
return z;
}
int
f4 (char *x, char **y, int z)
{
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" } */
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" } */
/* These are correct, no warning. */
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
z += strncasecmp (s3, s4, sizeof (s3));
z += strncasecmp (s3, s4, sizeof (s4));
return z;
}
/* { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" } */