Hi,
    Shall it a good idea to add new warning -Wsizeof-array-argument that
warns when sizeof is applied on parameter declared as an array ?
Similar to clang's -Wsizeof-array-argument:
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110613/042812.html
This was also reported as PR6940:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=6940

I have attached a patch that adds the warning to C front-end.
I implemented it by adding a new member BOOL_BITFIELD is_array_parm to
tree_parm_decl. Not sure if that's a good approach.
Also should it be enabled by -Wall or -Wextra or only by
-Wsizeof-array-argument ?
Currently I have made it enabled by -Wall along with -Wsizeof-array-argument.

Bootstrapped on x86_64-unknown-linux-gnu.

[gcc]
* tree-core.h (tree_parm_decl): Add new member BOOL_BITFIELD is_array_parm
* tree.h (SET_PARM_DECL_IS_ARRAY): New macro.
            (PARM_DECL_ARRAY_P): New macro.

[gcc/c]
* c-decl.c (push_parm_decl): Call SET_PARM_DECL_IS_ARRAY.
* c-typeck.c (c_expr_sizeof_expr): Add check for sizeof-array-argument warning.

[gcc/c-family]
* c.opt (-Wsizeof-array-argument): New option.

[gcc/testsuite/gcc.dg]
* sizeof-array-argument.c: New test-case.

Thanks and Regards,
Prathamesh
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h	(revision 209800)
+++ gcc/tree-core.h	(working copy)
@@ -1411,6 +1411,7 @@ struct GTY(()) tree_const_decl {
 struct GTY(()) tree_parm_decl {
   struct tree_decl_with_rtl common;
   rtx incoming_rtl;
+  BOOL_BITFIELD is_array_parm;
 };
 
 struct GTY(()) tree_decl_with_vis {
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 209800)
+++ gcc/tree.h	(working copy)
@@ -1742,6 +1742,7 @@ extern void protected_set_expr_location
 #define TYPE_LANG_SPECIFIC(NODE) \
   (TYPE_CHECK (NODE)->type_with_lang_specific.lang_specific)
 
+
 #define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type_non_common.values)
 #define TYPE_DOMAIN(NODE) (ARRAY_TYPE_CHECK (NODE)->type_non_common.values)
 #define TYPE_FIELDS(NODE) \
@@ -2258,6 +2259,12 @@ extern void decl_value_expr_insert (tree
 #define DECL_INCOMING_RTL(NODE) \
   (PARM_DECL_CHECK (NODE)->parm_decl.incoming_rtl)
 
+#define SET_PARM_DECL_IS_ARRAY(NODE, val) \
+  (PARM_DECL_CHECK (NODE)->parm_decl.is_array_parm = (val))
+
+#define PARM_DECL_ARRAY_P(NODE) \
+  (PARM_DECL_CHECK (NODE)->parm_decl.is_array_parm != 0)
+
 /* Nonzero for a given ..._DECL node means that no warnings should be
    generated just because this node is unused.  */
 #define DECL_IN_SYSTEM_HEADER(NODE) \
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 209800)
+++ gcc/c/c-decl.c	(working copy)
@@ -4626,13 +4626,14 @@ push_parm_decl (const struct c_parm *par
 {
   tree attrs = parm->attrs;
   tree decl;
+  int is_array;
 
   decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL,
 			 &attrs, expr, NULL, DEPRECATED_NORMAL);
   decl_attributes (&decl, attrs, 0);
-
+  is_array = parm->declarator->kind == cdk_array;
+  SET_PARM_DECL_IS_ARRAY (decl, is_array); 
   decl = pushdecl (decl);
-
   finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
 }
 
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(revision 209800)
+++ gcc/c/c-typeck.c	(working copy)
@@ -2730,6 +2730,12 @@ c_expr_sizeof_expr (location_t loc, stru
   else
     {
       bool expr_const_operands = true;
+      if (warn_sizeof_array_argument && TREE_CODE (expr.value) == PARM_DECL && PARM_DECL_ARRAY_P (expr.value))
+	{
+	  warning_at (loc, 0, "sizeof on array parameter %<%s%> shall return size of %qT",
+		      IDENTIFIER_POINTER (DECL_NAME (expr.value)), expr.original_type); 
+	  inform (DECL_SOURCE_LOCATION (expr.value), "declared here");
+	}
       tree folded_expr = c_fully_fold (expr.value, require_constant_value,
 				       &expr_const_operands);
       ret.value = c_sizeof (loc, TREE_TYPE (folded_expr));
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 209800)
+++ gcc/c-family/c.opt	(working copy)
@@ -509,6 +509,9 @@ Warn about missing fields in struct init
 Wsizeof-pointer-memaccess
 C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
 
+Wsizeof-array-argument
+C Var(warn_sizeof_array_argument) Warning LangEnabledBy(C,Wall)
+
 Wsuggest-attribute=format
 C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
 Warn about functions which might be candidates for format attributes
Index: gcc/testsuite/gcc.dg/sizeof-array-argument.c
===================================================================
--- gcc/testsuite/gcc.dg/sizeof-array-argument.c	(revision 0)
+++ gcc/testsuite/gcc.dg/sizeof-array-argument.c	(working copy)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-Wsizeof-array-argument" } */
+
+int foo(int a[])
+{
+  return (int) sizeof (a);  /* { dg-warning "sizeof on array parameter" } */
+}
+
+int bar(int x, int b[3])
+{
+  return x + (int) sizeof (b);  /* { dg-warning "sizeof on array parameter" } */
+}
+
+int f(int *p)
+{
+  return (int) sizeof (*p);
+}

Reply via email to