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); +}