aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
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-family
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-family')
-rw-r--r--gcc/c-family/ChangeLog8
-rw-r--r--gcc/c-family/c-common.c143
-rw-r--r--gcc/c-family/c-common.def6
-rw-r--r--gcc/c-family/c-common.h7
-rw-r--r--gcc/c-family/c-opts.c5
-rw-r--r--gcc/c-family/c.opt3
6 files changed, 167 insertions, 5 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c460b35..2ce3f59 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,11 @@
+2012-08-17 Jakub Jelinek <jakub@redhat.com>
+
+ * 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.
+
2012-08-10 Richard Guenther <rguenther@suse.de>
* c-pretty-print.c (pp_c_expression): Handle anonymous SSA names.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index ab3eb0a..502613a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1841,6 +1841,149 @@ strict_aliasing_warning (tree otype, tree type, tree expr)
return false;
}
+/* Warn about memset (&a, 0, sizeof (&a)); and similar mistakes with
+ sizeof as last operand of certain builtins. */
+
+void
+sizeof_pointer_memaccess_warning (location_t 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;
+
+ 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:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCAT:
+ strop = true;
+ /* FALLTHRU */
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMCMP:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 1);
+ dest = VEC_index (tree, params, 0);
+ break;
+ case BUILT_IN_MEMSET:
+ if (VEC_length (tree, params) < 3)
+ return;
+ dest = VEC_index (tree, params, 0);
+ break;
+ case BUILT_IN_STRNDUP:
+ src = VEC_index (tree, params, 0);
+ strop = true;
+ break;
+ default:
+ break;
+ }
+
+ if (dest
+ && (tem = tree_strip_nop_conversions (dest))
+ && POINTER_TYPE_P (TREE_TYPE (tem))
+ && comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
+ return;
+
+ if (src
+ && (tem = tree_strip_nop_conversions (src))
+ && POINTER_TYPE_P (TREE_TYPE (tem))
+ && comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
+ return;
+
+ if (dest)
+ {
+ if (!TYPE_P (sizeof_arg)
+ && operand_equal_p (dest, sizeof_arg, 0)
+ && comp_types (TREE_TYPE (dest), type))
+ {
+ if (TREE_CODE (sizeof_arg) == 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 "
+ "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 destination; 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 destination; 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 destination; expected %qT "
+ "or an explicit length", callee, TREE_TYPE (dest),
+ TREE_TYPE (TREE_TYPE (dest)));
+ return;
+ }
+ }
+
+ if (src)
+ {
+ if (!TYPE_P (sizeof_arg)
+ && operand_equal_p (src, sizeof_arg, 0)
+ && comp_types (TREE_TYPE (src), type))
+ {
+ if (TREE_CODE (sizeof_arg) == 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 "
+ "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 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 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 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
of `main'. */
diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def
index 2a7df88..b6df9a3 100644
--- a/gcc/c-family/c-common.def
+++ b/gcc/c-family/c-common.def
@@ -2,7 +2,7 @@
additional tree codes used in the GNU C compiler (see tree.def
for the standard codes).
Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
- 1999, 2000, 2001, 2004, 2005, 2007, 2009, 2010
+ 1999, 2000, 2001, 2004, 2005, 2007, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Written by Benjamin Chelf <chelf@codesourcery.com>
@@ -53,6 +53,10 @@ DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1)
number. */
DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3)
+/* Represents a 'sizeof' expression during C++ template expansion,
+ or for the purpose of -Wsizeof-pointer-memaccess warning. */
+DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1)
+
/*
Local variables:
mode:c
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 050112e..9298e3d 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1,6 +1,6 @@
/* Definitions for c-common.c.
- Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+ Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -768,6 +768,9 @@ 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,
+ bool (*) (tree, tree));
extern void warnings_for_convert_and_check (tree, tree, tree);
extern tree convert_and_check (tree, tree);
extern void overflow_warning (location_t, tree);
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 2fa59dc..29121b5 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1,6 +1,6 @@
/* C/ObjC/C++ command line option handling.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+ 2012 Free Software Foundation, Inc.
Contributed by Neil Booth.
This file is part of GCC.
@@ -374,6 +374,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
warn_return_type = value;
warn_sequence_point = value; /* Was C only. */
warn_switch = value;
+ warn_sizeof_pointer_memaccess = value;
if (warn_strict_aliasing == -1)
set_Wstrict_aliasing (&global_options, value);
warn_address = value;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 981b7ab..914d110 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -474,6 +474,9 @@ Wmissing-field-initializers
C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Warning EnabledBy(Wextra)
Warn about missing fields in struct initializers
+Wsizeof-pointer-memaccess
+C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning
+
Wsuggest-attribute=format
C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
Warn about functions which might be candidates for format attributes