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