Commit 3a785c97 by Jakub Jelinek Committed by Jakub Jelinek

re PR c/54381 (-Wsizeof-pointer-memaccess refers to "destination" for strncmp)

	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.

From-SVN: r192406
parent 313465bb
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
......
......@@ -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
......
......@@ -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);
......
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.
......
......@@ -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
......
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
......
......@@ -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);
}
......
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
......
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment