aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2012-10-12 20:23:03 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2012-10-12 20:23:03 +0200
commit3a785c97fa626dcc0ad2899d762e30da1782636a (patch)
tree53a2b873d7fe4f0c44a653a6e7c37c843b92ade2 /gcc/c/c-parser.c
parent313465bbbd04019184339161f0e30a46a5c0e4ab (diff)
downloadgcc-3a785c97fa626dcc0ad2899d762e30da1782636a.zip
gcc-3a785c97fa626dcc0ad2899d762e30da1782636a.tar.gz
gcc-3a785c97fa626dcc0ad2899d762e30da1782636a.tar.bz2
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
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r--gcc/c/c-parser.c71
1 files changed, 36 insertions, 35 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index bea9791..bfa98af 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