]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/6940 (taking sizeof array parameter should trigger a warning)
authorMarek Polacek <polacek@redhat.com>
Sun, 6 Jul 2014 19:00:10 +0000 (19:00 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Sun, 6 Jul 2014 19:00:10 +0000 (19:00 +0000)
PR c/6940
* doc/invoke.texi: Document -Wsizeof-array-argument.
c-family/
* c.opt (Wsizeof-array-argument): New option.
c/
* c-decl.c (grokdeclarator): Set C_ARRAY_PARAMETER.
* c-tree.h (C_ARRAY_PARAMETER): Define.
* c-typeck.c (c_expr_sizeof_expr): Warn when using sizeof on an array
function parameter.
cp/
* cp-tree.h (DECL_ARRAY_PARAMETER_P): Define.
* decl.c (grokdeclarator): Set DECL_ARRAY_PARAMETER_P.
* typeck.c (cxx_sizeof_expr): Warn when using sizeof on an array
function parameter.
testsuite/
* c-c++-common/Wsizeof-pointer-memaccess1.c: Use
-Wno-sizeof-array-argument.
* c-c++-common/Wsizeof-pointer-memaccess2.c: Likewise.
* g++.dg/warn/Wsizeof-pointer-memaccess-1.C: Likewise.
* gcc.dg/Wsizeof-pointer-memaccess1.c: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
* g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
* gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Likewise.
* c-c++-common/sizeof-array-argument.c: New test.
* gcc.dg/vla-5.c: Add dg-warnings.
../libgomp/ * testsuite/libgomp.c/appendix-a/a.29.1.c (f): Add dg-warnings.

From-SVN: r212312

24 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/c/c-tree.h
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/typeck.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c
gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c
gcc/testsuite/c-c++-common/sizeof-array-argument.c [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
gcc/testsuite/g++.dg/warn/Wsizeof-pointer-memaccess-1.C
gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
gcc/testsuite/gcc.dg/vla-5.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c

index 0f1a80d9550b491af409a9c227c6e18b3682239f..6f8b251d0d8733e3e79233d09e785871b687aba4 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-06  Marek Polacek  <polacek@redhat.com>
+
+       PR c/6940
+       * doc/invoke.texi: Document -Wsizeof-array-argument.
+
 2014-07-05  Gerald Pfeifer  <gerald@pfeifer.com>
 
        * wide-int.h (wide_int_storage): Change declaration from struct 
index d667ed862515b08a9ce131765dce30571bd3e844..5bd9c1e435ca72256f00f8b52f74587031e9ed90 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-06  Marek Polacek  <polacek@redhat.com>
+
+       PR c/6940
+       * c.opt (Wsizeof-array-argument): New option.
+
 2014-07-03  Jakub Jelinek  <jakub@redhat.com>
 
        * c-ada-spec.c (dump_ada_nodes): Don't call qsort if 
index c89040abf9ee962fb379c50a907b0d0b93b4a25d..faef774e8c4c8dd4547ffecb7981158607fec97f 100644 (file)
@@ -534,6 +534,10 @@ Wsizeof-pointer-memaccess
 C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
 Warn about suspicious length parameters to certain string functions if the argument uses sizeof
 
+Wsizeof-array-argument
+C ObjC C++ ObjC++ Var(warn_sizeof_array_argument) Warning Init(1)
+Warn when sizeof is applied on a parameter declared as an array
+
 Wsuggest-attribute=format
 C ObjC C++ ObjC++ Var(warn_suggest_attribute_format) Warning
 Warn about functions which might be candidates for format attributes
index 68abca4dfb1ef9eebf6e5f5d4d08b1feaced4448..80ad172c5963db4ffdc04da6a19358964b3f7273 100644 (file)
@@ -1,3 +1,11 @@
+2014-07-06  Marek Polacek  <polacek@redhat.com>
+
+       PR c/6940
+       * c-decl.c (grokdeclarator): Set C_ARRAY_PARAMETER.
+       * c-tree.h (C_ARRAY_PARAMETER): Define.
+       * c-typeck.c (c_expr_sizeof_expr): Warn when using sizeof on an array
+       function parameter.
+
 2014-07-02  Jan Hubicka  <hubicka@ucw.cz>
            Chen Gang <gang.chen.5i5j@gmail.com>
 
index 3dec90b23ed52edfdbbafd156b38cec4234ebbe3..0ca2e0d58f4c355389ab0722bc26fe3f007f9f00 100644 (file)
@@ -6103,6 +6103,7 @@ grokdeclarator (const struct c_declarator *declarator,
     if (decl_context == PARM)
       {
        tree promoted_type;
+       bool array_parameter_p = false;
 
        /* A parameter declared as an array of T is really a pointer to T.
           One declared as a function is really a pointer to a function.  */
@@ -6124,6 +6125,7 @@ grokdeclarator (const struct c_declarator *declarator,
                          "attributes in parameter array declarator ignored");
 
            size_varies = false;
+           array_parameter_p = true;
          }
        else if (TREE_CODE (type) == FUNCTION_TYPE)
          {
@@ -6148,6 +6150,7 @@ grokdeclarator (const struct c_declarator *declarator,
                           PARM_DECL, declarator->u.id, type);
        if (size_varies)
          C_DECL_VARIABLE_SIZE (decl) = 1;
+       C_ARRAY_PARAMETER (decl) = array_parameter_p;
 
        /* Compute the type actually passed in the parmlist,
           for the case where there is no prototype.
index 133930f4a098e008ded0bf1c65bd071fb7a5121b..f97d0d5ba9b49daf3292f0c3494310df36e50dd0 100644 (file)
@@ -66,6 +66,9 @@ along with GCC; see the file COPYING3.  If not see
 /* For a FUNCTION_DECL, nonzero if it was an implicit declaration.  */
 #define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
 
+/* For a PARM_DECL, nonzero if it was declared as an array.  */
+#define C_ARRAY_PARAMETER(NODE) DECL_LANG_FLAG_0 (NODE)
+
 /* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
    been declared.  */
 #define C_DECL_DECLARED_BUILTIN(EXP)           \
index 35bfd1498769e4991b99d65422d4844969d8dedc..06fd565f7708f2c8c9578199dd98f36e018a2442 100644 (file)
@@ -2731,6 +2731,16 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
   else
     {
       bool expr_const_operands = true;
+
+      if (TREE_CODE (expr.value) == PARM_DECL
+         && C_ARRAY_PARAMETER (expr.value))
+       {
+         if (warning_at (loc, OPT_Wsizeof_array_argument,
+                         "%<sizeof%> on array function parameter %qE will "
+                         "return size of %qT", 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 dd6279af49c8c2b411ce34b695176471fb2c60be..93b05fa7326eaef766a65a80ff626aec01fbca49 100644 (file)
@@ -1,3 +1,11 @@
+2014-07-06  Marek Polacek  <polacek@redhat.com>
+
+       PR c/6940
+       * cp-tree.h (DECL_ARRAY_PARAMETER_P): Define.
+       * decl.c (grokdeclarator): Set DECL_ARRAY_PARAMETER_P.
+       * typeck.c (cxx_sizeof_expr): Warn when using sizeof on an array
+       function parameter.
+
 2014-07-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * pt.c (convert_template_argument): Use inform instead of error in
index 1e9e1afd2fe2349d5bebac6ca55887904449144a..4a5cb989977e8b921c7c4bb2fbc460d784b5269a 100644 (file)
@@ -146,6 +146,7 @@ c-common.h, not after.
       DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
       USING_DECL_TYPENAME_P (in USING_DECL)
       DECL_VLA_CAPTURE_P (in FIELD_DECL)
+      DECL_ARRAY_PARAMETER_P (in PARM_DECL)
    2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
       DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
    3: DECL_IN_AGGR_P.
@@ -3681,6 +3682,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define DECL_VLA_CAPTURE_P(NODE) \
   DECL_LANG_FLAG_1 (FIELD_DECL_CHECK (NODE))
 
+/* Nonzero for PARM_DECL node means that this is an array function
+   parameter, i.e, a[] rather than *a.  */
+#define DECL_ARRAY_PARAMETER_P(NODE) \
+  DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE))
+
 /* Nonzero for FIELD_DECL node means that this field is a base class
    of the parent object, as opposed to a member field.  */
 #define DECL_FIELD_IS_BASE(NODE) \
index 909f762e93c42c39f23fd514c97976f5ea27f13d..5ab8ccd2588b08ca516d42c2563d911e2bf35c1a 100644 (file)
@@ -8816,6 +8816,7 @@ grokdeclarator (const cp_declarator *declarator,
   bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
   bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
   bool late_return_type_p = false;
+  bool array_parameter_p = false;
   source_location saved_loc = input_location;
   const char *errmsg;
 
@@ -10454,6 +10455,7 @@ grokdeclarator (const cp_declarator *declarator,
          /* Transfer const-ness of array into that of type pointed to.  */
          type = build_pointer_type (TREE_TYPE (type));
          type_quals = TYPE_UNQUALIFIED;
+         array_parameter_p = true;
        }
       else if (TREE_CODE (type) == FUNCTION_TYPE)
        type = build_pointer_type (type);
@@ -10474,6 +10476,7 @@ grokdeclarator (const cp_declarator *declarator,
     if (decl_context == PARM)
       {
        decl = cp_build_parm_decl (unqualified_id, type);
+       DECL_ARRAY_PARAMETER_P (decl) = array_parameter_p;
 
        bad_specifiers (decl, BSP_PARM, virtualp,
                        memfn_quals != TYPE_UNQUALIFIED,
index 9758dfe44d934d2bfce1cabd7c1c51e125147bfe..a1ca9370e56cc1506ed12f6e99c2f3b6a8afd1c4 100644 (file)
@@ -1614,6 +1614,15 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
       && DECL_TEMPLATE_INSTANTIATION (e))
     instantiate_decl (e, /*defer_ok*/true, /*expl_inst_mem*/false);
 
+  if (TREE_CODE (e) == PARM_DECL
+      && DECL_ARRAY_PARAMETER_P (e)
+      && (complain & tf_warning))
+    {
+      if (warning (OPT_Wsizeof_array_argument, "%<sizeof%> on array function "
+                  "parameter %qE will return size of %qT", e, TREE_TYPE (e)))
+       inform (DECL_SOURCE_LOCATION (e), "declared here");
+    }
+
   e = mark_type_use (e);
 
   if (TREE_CODE (e) == COMPONENT_REF
index 046ea58077219bf121423cc2f4bb2740ff026885..111a67e60f2015012e843fa51e01d2111cfb0230 100644 (file)
@@ -266,7 +266,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wredundant-decls  -Wno-return-local-addr @gol
 -Wreturn-type  -Wsequence-point  -Wshadow  -Wno-shadow-ivar @gol
 -Wsign-compare  -Wsign-conversion -Wfloat-conversion @gol
--Wsizeof-pointer-memaccess @gol
+-Wsizeof-pointer-memaccess  -Wsizeof-array-argument @gol
 -Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
 -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
 -Wsuggest-attribute=@r{[}pure@r{|}const@r{|}noreturn@r{|}format@r{]} @gol
@@ -4676,6 +4676,13 @@ but a pointer, and suggests a possible fix, or about
 @code{memcpy (&foo, ptr, sizeof (&foo));}.  This warning is enabled by
 @option{-Wall}.
 
+@item -Wsizeof-array-argument
+@opindex Wsizeof-array-argument
+@opindex Wno-sizeof-array-argument
+Warn when the @code{sizeof} operator is applied to a parameter that is
+declared as an array in a function definition.  This warning is enabled by
+default for C and C++ programs.
+
 @item -Waddress
 @opindex Waddress
 @opindex Wno-address
index c24f30173ddb29137fe7058f63008a2e0b3afcb8..25084765568861640f5056a2f7cadef2a61b4eab 100644 (file)
@@ -1,3 +1,17 @@
+2014-07-06  Marek Polacek  <polacek@redhat.com>
+
+       PR c/6940
+       * c-c++-common/Wsizeof-pointer-memaccess1.c: Use
+       -Wno-sizeof-array-argument.
+       * c-c++-common/Wsizeof-pointer-memaccess2.c: Likewise.
+       * g++.dg/warn/Wsizeof-pointer-memaccess-1.C: Likewise.
+       * gcc.dg/Wsizeof-pointer-memaccess1.c: Likewise.
+       * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
+       * g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
+       * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Likewise.
+       * c-c++-common/sizeof-array-argument.c: New test.
+       * gcc.dg/vla-5.c: Add dg-warnings.
+
 2014-07-05  Jan Hubicka   <hubicka@ucw.cz>
 
        * g++.dg/ipa/devirt-26.C: Update testcase.
index 2a5f4193b214c6cfd407e3078b145635963fdfe4..8e829d61ae0b784fee319753bd916c4a3b2dbdff 100644 (file)
@@ -1,6 +1,6 @@
 /* Test -Wsizeof-pointer-memaccess warnings.  */
 /* { dg-do compile } */
-/* { dg-options "-Wall" } */
+/* { dg-options "-Wall -Wno-sizeof-array-argument" } */
 
 typedef __SIZE_TYPE__ size_t;
 #ifdef __cplusplus
index 73cdf0eaba7b83d85e83e940a5036895a4438222..fe17a7056abdab26e73744c95c3cc9a08f0bdfde 100644 (file)
@@ -1,6 +1,6 @@
 /* Test -Wsizeof-pointer-memaccess warnings.  */
 /* { dg-do compile } */
-/* { dg-options "-Wall -O2" } */
+/* { dg-options "-Wall -O2 -Wno-sizeof-array-argument" } */
 
 #define bos(ptr) __builtin_object_size (ptr, 1)
 #define bos0(ptr) __builtin_object_size (ptr, 0)
diff --git a/gcc/testsuite/c-c++-common/sizeof-array-argument.c b/gcc/testsuite/c-c++-common/sizeof-array-argument.c
new file mode 100644 (file)
index 0000000..eedfcee
--- /dev/null
@@ -0,0 +1,100 @@
+/* PR c/6940 */
+/* { dg-do compile } */
+
+/* Test -Wsizeof-array-argument warning.  */
+
+typedef int T[2][2];
+
+int
+fn1 (int a[])
+{
+  return sizeof a; /* { dg-warning "on array function parameter" } */
+}
+
+int
+fn2 (int x, int b[3])
+{
+  return x + sizeof b; /* { dg-warning "on array function parameter" } */
+}
+
+int
+fn3 (int *p)
+{
+  return sizeof p;
+}
+
+int fn4 (int *p);
+int
+fn4 (int p[])
+{
+  return sizeof p; /* { dg-warning "on array function parameter" } */
+}
+
+int fn5 (int x[]);
+int
+fn5 (int *x)
+{
+  return sizeof x;
+}
+
+#ifndef __cplusplus
+/* C++ doesn't know VLA unspec.  */
+int fn6 (int x[*]);
+int
+fn6 (int x[])
+{
+  return sizeof x; /* { dg-warning "on array function parameter" "" { target c } } */
+}
+#endif
+
+int
+fn7 (int x[][2])
+{
+  return sizeof x; /* { dg-warning "on array function parameter" } */
+}
+
+int
+fn8 (char *x[])
+{
+  return sizeof x; /* { dg-warning "on array function parameter" } */
+}
+
+int
+fn9 (char **x)
+{
+  return sizeof x;
+}
+
+#ifndef __cplusplus
+int
+fn10 (int a, char x[static sizeof a])
+{
+  return sizeof x; /* { dg-warning "on array function parameter" "" { target c } } */
+}
+
+int
+fn11 (a)
+  char a[];
+{
+  return sizeof a; /* { dg-warning "on array function parameter" "" { target c } } */
+}
+
+int
+fn12 (a)
+  char *a;
+{
+  return sizeof a;
+}
+#endif
+
+int
+fn13 (char (*x)[2])
+{
+  return sizeof x;
+}
+
+int
+fn14 (T t)
+{
+  return sizeof t; /* { dg-warning "on array function parameter" } */
+}
index 6cb39809d6ce5c4e74c8f9d5c74eaa2bb2128a53..8b5c33e24b3d7f6072df418bf7b58133dd16f049 100644 (file)
@@ -1,6 +1,6 @@
 // Test -Wsizeof-pointer-memaccess warnings.
 // { dg-do compile }
-// { dg-options "-Wall" }
+// { dg-options "-Wall -Wno-sizeof-array-argument" }
 // Test just twice, once with -O0 non-fortified, once with -O2 fortified.
 // { dg-skip-if "" { *-*-* }  { "*" } { "-O0" "-O2" } }
 // { dg-skip-if "" { *-*-* }  { "-flto" } { "" } }
index 9e2805d2b7466369ad571cb7a1fd549338571d87..0e99568d3f3d26d02281f3527e94ecb98a3b9281 100644 (file)
@@ -1,6 +1,6 @@
 // Test -Wsizeof-pointer-memaccess warnings.
 // { dg-do compile }
-// { dg-options "-Wall" }
+// { dg-options "-Wall -Wno-sizeof-array-argument" }
 // Test just twice, once with -O0 non-fortified, once with -O2 fortified.
 // { dg-skip-if "" { *-*-* }  { "*" } { "-O0" "-O2" } }
 // { dg-skip-if "" { *-*-* }  { "-flto" } { "" } }
index e2ba8769b9a5a40b9fe8aba930a2f4c900be9991..798cb6de0440de6c479f12bc69f7fc252e4ca4aa 100644 (file)
@@ -1,6 +1,6 @@
 // Test -Wsizeof-pointer-memaccess warnings.
 // { dg-do compile }
-// { dg-options "-Wall" }
+// { dg-options "-Wall -Wno-sizeof-array-argument" }
 
 typedef __SIZE_TYPE__ size_t;
 extern "C" void *memset (void *, int, size_t);
index b683be7ceff8307dc59a801d5c7c9c4c16479cf6..66be5a5c4b21929612f27cc11bf6c7d4f229a84e 100644 (file)
@@ -1,6 +1,6 @@
 /* Test -Wsizeof-pointer-memaccess warnings.  */
 /* { dg-do compile } */
-/* { dg-options "-Wall" } */
+/* { dg-options "-Wall -Wno-sizeof-array-argument" } */
 
 typedef __SIZE_TYPE__ size_t;
 extern void bzero (void *, size_t);
index 8d01bc616a77bc0a012227cb879c777558bb7995..a82f4efbdafabd1f2a7eb7c8c58de0678ae123e7 100644 (file)
@@ -1,6 +1,6 @@
 /* Test -Wsizeof-pointer-memaccess warnings.  */
 /* { dg-do compile } */
-/* { dg-options "-Wall" } */
+/* { dg-options "-Wall -Wno-sizeof-array-argument" } */
 /* Test just twice, once with -O0 non-fortified, once with -O2 fortified.  */
 /* { dg-skip-if "" { *-*-* }  { "*" } { "-O0" "-O2" } } */
 /* { dg-skip-if "" { *-*-* }  { "-flto" } { "" } } */
index f5256c4c4a37bb394532c24829b47a8b199b0ad5..2c253b5075841a48290ade342d8e6b4101def778 100644 (file)
@@ -13,12 +13,12 @@ void foo4(int j, int a[j]) {
 
 int foo5(int a, int b[*][*], int c[static sizeof(*b)]);
 int foo5(int a, int b[10][10], int c[400]) {
-  return sizeof (c);
+  return sizeof (c); /* { dg-warning "on array function parameter" } */
 }
 
 int foo6(int a, int b[*][*], int c[static sizeof(*b)]);
 int foo6(int a, int b[a][a], int c[sizeof(*b)]) {
-  return sizeof (c);
+  return sizeof (c); /* { dg-warning "on array function parameter" } */
 }
 
 void foo7(__typeof__ (int (*)(int o[*])) i);
index ee2e264e58bbe0489b7b8b1a3ce4c12dd46e1533..dbfc03cb8155a7232de3a0a6bbec9f52612081db 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-06  Marek Polacek  <polacek@redhat.com>
+
+       PR c/6940
+       * testsuite/libgomp.c/appendix-a/a.29.1.c (f): Add dg-warnings.
+
 2014-07-03  Jakub Jelinek  <jakub@redhat.com>
 
        * testsuite/lib/libgomp.exp (libgomp_target_compile): If $source
index 6f0f65fa03e701e48af633bdf4277bc0ca369c55..484321207c80f82f42994e066b96c4ee11b6988c 100644 (file)
@@ -11,8 +11,8 @@ f (int n, int B[n][n], int C[])
   E[1][1] = 4;
 #pragma omp parallel firstprivate(B, C, D, E)
   {
-    assert (sizeof (B) == sizeof (int (*)[n]));
-    assert (sizeof (C) == sizeof (int *));
+    assert (sizeof (B) == sizeof (int (*)[n])); /* { dg-warning "on array function parameter" } */
+    assert (sizeof (C) == sizeof (int *)); /* { dg-warning "on array function parameter" } */
     assert (sizeof (D) == 4 * sizeof (int));
     assert (sizeof (E) == n * n * sizeof (int));
     /* Private B and C have values of original B and C. */