aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2012-08-17 09:17:56 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2012-08-17 09:17:56 +0200
commit1a4049e7c504bedf3f485fd94a26902959a4ce2a (patch)
tree4109785fceb3bc788cf4f9ee1e8a0fc71649fdfb /gcc/c
parent138f5acd18aafd07cd4a034cb8e879dd0621544b (diff)
downloadgcc-1a4049e7c504bedf3f485fd94a26902959a4ce2a.zip
gcc-1a4049e7c504bedf3f485fd94a26902959a4ce2a.tar.gz
gcc-1a4049e7c504bedf3f485fd94a26902959a4ce2a.tar.bz2
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
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog13
-rw-r--r--gcc/c/c-parser.c64
-rw-r--r--gcc/c/c-tree.h6
-rw-r--r--gcc/c/c-typeck.c14
4 files changed, 85 insertions, 12 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 2c40784..72b5a4d 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 34d5a34..7536dc5 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 145df35..c07d994 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 5b710c3..99920ef 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))