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