diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-17 07:17:56 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-17 07:17:56 +0000 |
commit | f003f5dcb67d4c25184a57afe661122d934109be (patch) | |
tree | 4109785fceb3bc788cf4f9ee1e8a0fc71649fdfb /gcc/c | |
parent | c1420b840682a8a9ccb2263d882c69c3c1e3db55 (diff) | |
download | gcc-f003f5dcb67d4c25184a57afe661122d934109be.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190467 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 64 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 6 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 14 |
4 files changed, 85 insertions, 12 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 2c4078446fd..72b5a4d3aa2 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -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. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 34d5a34c808..7536dc56f05 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -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 diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 145df357af9..c07d994975d 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -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); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 5b710c32823..99920ef288b 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -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)) |