Warn about this:

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

This would allow eventually adding another semicolon in function
prototypes to separate a different feature.

So, make multiple lists of forward declarations of parameters
obsolescent, and produce a new diagnostic,
-Wmultiple-parameter-fwd-decl-lists, which diagnoses uses of this
obsolescent syntax.

Forward declarations of parameters are a rarely used feature, AFAIK,
(and having more than one would be even rarer) so this shouldn't be
problematic in -Wextra.  Eventually, we may want to move this into
a default diagnostic, and later an error.

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                              | 13 ++++++++++++-
 .../gcc.dg/Wmultiple-parameter-fwd-decl-lists.c  |  6 ++++++
 5 files changed, 32 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..12c7994c412 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 are 
an obsolescent feature");
+  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..b29d796d5e9 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,14 @@ 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,
+which is an obsolescent feature.
+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..d9baeedc137
--- /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