diff options
author | Jakub Jelinek <jakub@redhat.com> | 2012-10-12 20:23:03 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-10-12 20:23:03 +0200 |
commit | 3a785c97fa626dcc0ad2899d762e30da1782636a (patch) | |
tree | 53a2b873d7fe4f0c44a653a6e7c37c843b92ade2 /gcc/c/c-parser.c | |
parent | 313465bbbd04019184339161f0e30a46a5c0e4ab (diff) | |
download | gcc-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.c | 71 |
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 |