Warn about this:

        void f(int x; int x; int x);

Add a new diagnostic, -Wmultiple-parameter-fwd-decl-lists, which
diagnoses uses of this obsolescent syntax.

Add this diagnostic in -Wextra.

Forward declarations of parameters are very rarely used.  And functions
that need two forward declaractions of parameters are also quite rare.
This combination results in this code almost not existing in any code
base, which makes adding this to -Wextra okay.  FWIW, I've tried finding
such code using a code search engine, and didn't find any cases (but the
regex for that isn't easy to writei, so I wouldn't trust it).

gcc/c-family/ChangeLog:

        * c.opt: Add -Wmultiple-parameter-fwd-decl-lists

gcc/c/ChangeLog:

        * c-decl.cc (c_scope): Rename {warned > had}_forward_parm_decls.
        (mark_forward_parm_decls): Add
        -Wmultiple-parameter-fwd-decl-lists.

gcc/ChangeLog:

        * doc/invoke.texi: Document the new
        -Wmultiple-parameter-fwd-decl-lists.

gcc/testsuite/ChangeLog:

        * gcc.gd/Wmultiple-parameter-fwd-decl-lists.c: New test.

Cc: Christopher Bazley <chris.bazley.w...@gmail.com>
Cc: Martin Uecker <uec...@tugraz.at>
Signed-off-by: Alejandro Colomar <a...@kernel.org>
---
 gcc/c-family/c.opt                               |  4 ++++
 gcc/c/c-decl.cc                                  | 16 +++++++++-------
 gcc/doc/extend.texi                              |  2 +-
 gcc/doc/invoke.texi                              | 12 +++++++++++-
 .../gcc.dg/Wmultiple-parameter-fwd-decl-lists.c  |  6 ++++++
 5 files changed, 31 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wmultiple-parameter-fwd-decl-lists.c

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 3f5e2f0874d..4fd8770b65c 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1086,6 +1086,10 @@ Wmultiple-inheritance
 C++ ObjC++ Var(warn_multiple_inheritance) Warning
 Warn on direct multiple inheritance.
 
+Wmultiple-parameter-fwd-decl-lists
+C ObjC Var(warn_multiple_parameter_fwd_decl_lists) Warning EnabledBy(Wextra)
+Warn for multiple lists of forward declarations of function parameters.
+
 Wmultistatement-macros
 C ObjC C++ ObjC++ Var(warn_multistatement_macros) Warning LangEnabledBy(C ObjC 
C++ ObjC++,Wall)
 Warn about unsafe macros expanding to multiple statements used as a body of a 
clause such as if, else, while, switch, or for.
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 62a0545947e..763ee6ab7e1 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -507,7 +507,7 @@ struct GTY((chain_next ("%h.outer"))) c_scope {
   /* True if we already complained about forward parameter decls
      in this scope.  This prevents double warnings on
      foo (int a; int b; ...)  */
-  BOOL_BITFIELD warned_forward_parm_decls : 1;
+  BOOL_BITFIELD had_forward_parm_decls : 1;
 
   /* True if this is the outermost block scope of a function body.
      This scope contains the parameters, the local variables declared
@@ -6269,12 +6269,14 @@ mark_forward_parm_decls (void)
 {
   struct c_binding *b;
 
-  if (pedantic && !current_scope->warned_forward_parm_decls)
-    {
-      pedwarn (input_location, OPT_Wpedantic,
-              "ISO C forbids forward parameter declarations");
-      current_scope->warned_forward_parm_decls = true;
-    }
+  if (current_scope->had_forward_parm_decls)
+    warning_at (input_location, OPT_Wmultiple_parameter_fwd_decl_lists,
+               "more than one list of forward declarations of parameters");
+  if (pedantic && !current_scope->had_forward_parm_decls)
+    pedwarn (input_location, OPT_Wpedantic,
+            "ISO C forbids forward parameter declarations");
+
+  current_scope->had_forward_parm_decls = true;
 
   for (b = current_scope->bindings; b; b = b->prev)
     if (TREE_CODE (b->decl) == PARM_DECL)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 2922d9e9839..2b92dee5cfd 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -675,7 +675,7 @@ declaration}, and it serves the purpose of making the name 
@code{len}
 known when the declaration of @code{data} is parsed.
 
 You can write any number of such parameter forward declarations in the
-parameter list.  They can be separated by commas or semicolons, but the
+parameter list.  They can be separated by commas, and the
 last one must end with a semicolon, which is followed by the ``real''
 parameter declarations.  Each forward declaration must match a ``real''
 declaration in parameter name and data type.  ISO C99 does not support
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d0c13d4a24e..25e64dc5024 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -540,7 +540,9 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-Wbad-function-cast -Wdeprecated-non-prototype -Wfree-labels
 -Wmissing-declarations -Wmissing-parameter-name -Wmissing-parameter-type
 -Wdeclaration-missing-parameter-type -Wmissing-prototypes
--Wmissing-variable-declarations -Wnested-externs -Wold-style-declaration
+-Wmissing-variable-declarations
+-Wmultiple-parameter-fwd-decl-lists
+-Wnested-externs -Wold-style-declaration
 -Wold-style-definition -Wstrict-prototypes -Wtraditional
 -Wtraditional-conversion -Wdeclaration-after-statement -Wpointer-sign}
 
@@ -6682,6 +6684,7 @@ name is still supported, but the newer name is more 
descriptive.)
 -Wmissing-parameter-name @r{(C/ObjC only)}
 -Wmissing-parameter-type @r{(C/ObjC only)}
 -Wold-style-declaration @r{(C/ObjC only)}
+-Wmultiple-parameter-fwd-decl-lists @r{(C/ObjC only)}
 -Woverride-init @r{(C/ObjC only)}
 -Wredundant-move @r{(C++ and Objective-C++ only)}
 -Wshift-negative-value @r{(in C++11 to C++17 and in C99 and newer)}
@@ -10535,6 +10538,13 @@ is not considered an old-style definition in C23 mode, 
because it is
 equivalent to @samp{(void)} in that case, but is considered an
 old-style definition for older standards.
 
+@opindex Wmultiple-parameter-fwd-decl-lists
+@opindex Wno-multiple-parameter-fwd-decl-lists
+@item -Wmultiple-parameter-fwd-decl-lists @r{(C and Objective-C only)}
+Warn if more than one list of forward declarations of parameters
+appears in a function prototype.
+This warning is also enabled by @option{-Wextra}.
+
 @opindex Wdeprecated-non-prototype
 @opindex Wno-deprecated-non-prototype
 @item -Wdeprecated-non-prototype @r{(C and Objective-C only)}
diff --git a/gcc/testsuite/gcc.dg/Wmultiple-parameter-fwd-decl-lists.c 
b/gcc/testsuite/gcc.dg/Wmultiple-parameter-fwd-decl-lists.c
new file mode 100644
index 00000000000..c3edbf6a494
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wmultiple-parameter-fwd-decl-lists.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-Wmultiple-parameter-fwd-decl-lists" } */
+
+void f(int n, int m; int n, int m);
+void g(int n; int m; int n, int m); /* { dg-warning "more than one list of 
forward declarations" } */
+void h(int n; int n; int n); /* { dg-warning "more than one list of forward 
declarations" } */
-- 
2.50.1

Reply via email to