While this syntax is not standard, there's a certain degree of consensus within the C Committee that, if this was ever standardized, there's a preference to have a single list of forward declarations of parameters. 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, so this shouldn't be problematic in -Wextra. Eventually, we may want to move this into a default diagnostic, and later an error. Cc: Christopher Bazley <[email protected]> Cc: Martin Uecker <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> --- Hi! I've implemented this diagnostic to try to unify code using forward declarations of parameters into a single syntax, where there's a single list of forward declarations of parameters. I have tested this by compiling the compiler and then compiling the following test case: alx@debian:~/tmp$ cat fwd.c | nl 1 //void f(int n, int n; int n); // error 2 void g(int n; int n; int n); 3 void h(int n, int m; int n, int m); 4 void i(int n; int n; int n; int n, int m); alx@debian:~/tmp$ /opt/local/gnu/gcc/fwd/bin/gcc -S -Wmultiple-parameter-fwd-decl-lists fwd.c fwd.c:2:1: warning: More than one list of forward declarations of parameters are an obsolescent feature [-Wmultiple-parameter-fwd-decl-lists] 2 | void g(int n; int n; int n); | ^~~~ fwd.c:4:1: warning: More than one list of forward declarations of parameters are an obsolescent feature [-Wmultiple-parameter-fwd-decl-lists] 4 | void i(int n; int n; int n; int n, int m); | ^~~~ fwd.c:4:1: warning: More than one list of forward declarations of parameters are an obsolescent feature [-Wmultiple-parameter-fwd-decl-lists] I haven't yet run regression tests, which is why this is still an RFC, and not a PATCH. I'll do that when I stay in a place for an entire day. Also, I'll write changelogs once I've tested it and we agree this is something we want. WDYT? Have a lovely day! Alex gcc/c-family/c.opt | 4 ++++ gcc/c/c-decl.cc | 11 ++++++++--- gcc/doc/extend.texi | 2 +- gcc/doc/invoke.texi | 13 ++++++++++++- gcc/testsuite/gcc.dg/Wold-style-fwd-declaration.c | 6 ++++++ 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wold-style-fwd-declaration.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 77006cacdb7..69ded166f87 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 @@ -6261,12 +6261,17 @@ mark_forward_parm_decls (void) { struct c_binding *b; - if (pedantic && !current_scope->warned_forward_parm_decls) + 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->warned_forward_parm_decls = true; } + 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 cc9005439a4..2cfc0542b89 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 4bec80ac205..a5187e01d34 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -539,7 +539,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} @@ -6664,6 +6666,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)} @@ -10517,6 +10520,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/Wold-style-fwd-declaration.c b/gcc/testsuite/gcc.dg/Wold-style-fwd-declaration.c new file mode 100644 index 00000000000..756b612e597 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wold-style-fwd-declaration.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" } */ Range-diff against v0: -: ----------- > 1: fd77f2ea556 c: Deprecate more than one list of forward declarations of parameters -- 2.50.1
