This is another recent GCC extension whose use is apparently difficult to spot in code reviews.
The name of the option is due to Jonathan Wakely. Part of it could apply to C++ as well (for labels at the end of a compound statement). gcc/c-family/ * c-opts.cc (c_common_post_options): Initialize warn_free_labels. * c.opt (Wfree-labels): New option. * c.opt.urls: Regenerate. gcc/c/ * c-parser.cc (c_parser_compound_statement_nostart): Use OPT_Wfree_labels for warning about labels on declarations. (c_parser_compound_statement_nostart): Use OPT_Wfree_labels for warning about labels at end of compound statements. gcc/ * doc/invoke.texi: Document -Wfree-labels. gcc/testsuite/ * gcc.dg/Wfree-labels-1.c: New test. * gcc.dg/Wfree-labels-2.c: New test. * gcc.dg/Wfree-labels-3.c: New test. --- gcc/c-family/c-opts.cc | 5 +++++ gcc/c-family/c.opt | 4 ++++ gcc/c-family/c.opt.urls | 3 +++ gcc/c/c-parser.cc | 5 +++-- gcc/doc/invoke.texi | 14 +++++++++++++- gcc/testsuite/gcc.dg/Wfree-labels-1.c | 18 ++++++++++++++++++ gcc/testsuite/gcc.dg/Wfree-labels-2.c | 18 ++++++++++++++++++ gcc/testsuite/gcc.dg/Wfree-labels-3.c | 18 ++++++++++++++++++ 8 files changed, 82 insertions(+), 3 deletions(-) diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 127f9553e0c..e90730adc34 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -993,6 +993,11 @@ c_common_post_options (const char **pfilename) = ((pedantic && !flag_isoc23 && warn_c11_c23_compat != 0) || warn_c11_c23_compat > 0); + /* Likewise for -Wfree-labels. */ + if (warn_free_labels == -1) + warn_free_labels = ((pedantic && !flag_isoc23 && warn_c11_c23_compat != 0) + || warn_c11_c23_compat > 0); + /* -Wshift-negative-value is enabled by -Wextra in C99 and C++11 to C++17 modes. */ if (warn_shift_negative_value == -1) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 61cfe33c251..9226e9d7472 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -828,6 +828,10 @@ Wframe-address C ObjC C++ ObjC++ Var(warn_frame_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn when __builtin_frame_address or __builtin_return_address is used unsafely. +Wfree-labels +C ObjC Var(warn_free_labels) Init(-1) Warning +Warn about labels on declarations and at the end of compound statements. + Wglobal-module C++ ObjC++ Var(warn_global_module) Warning Init(1) Warn about the global module fragment not containing only preprocessing directives. diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index 04f8e2ee008..f2595b9dfc3 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -418,6 +418,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Wformat) Wframe-address UrlSuffix(gcc/Warning-Options.html#index-Wframe-address) +Wfree-labels +UrlSuffix(gcc/Warning-Options.html#index-Wfree-labels) + Wglobal-module UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wglobal-module) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 70fbf940835..413eaae5fe3 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -7403,7 +7403,7 @@ c_parser_compound_statement_nostart (c_parser *parser) && (have_std_attrs = true))) { if (last_label) - pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic, + pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wfree_labels, "a label can only be part of a statement and " "a declaration is not a statement"); /* It's unlikely we'll see a nested loop in a declaration in @@ -7550,7 +7550,8 @@ c_parser_compound_statement_nostart (c_parser *parser) parser->error = false; } if (last_label) - pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement"); + pedwarn_c11 (label_loc, OPT_Wfree_labels, + "label at end of compound statement"); location_t endloc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 36d79d1c76b..6c2a755a015 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -520,7 +520,7 @@ Objective-C and Objective-C++ Dialects}. } @item C and Objective-C-only Warning Options -@gccoptlist{-Wbad-function-cast -Wmissing-declarations +@gccoptlist{-Wbad-function-cast -Wfree-labels -Wmissing-declarations -Wmissing-parameter-name -Wmissing-parameter-type -Wdeclaration-missing-parameter-type -Wmissing-prototypes -Wmissing-variable-declarations -Wnested-externs -Wold-style-declaration @@ -6366,6 +6366,7 @@ name is still supported, but the newer name is more descriptive.) -Wempty-body -Wenum-conversion @r{(only for C/ObjC)} -Wexpansion-to-defined +-Wfree-labels @r{(C/ObjC only)} -Wignored-qualifiers @r{(only for C/C++)} -Wimplicit-fallthrough=3 -Wmaybe-uninitialized @@ -10011,6 +10012,17 @@ Do not warn if certain built-in macros are redefined. This suppresses warnings for redefinition of @code{__TIMESTAMP__}, @code{__TIME__}, @code{__DATE__}, @code{__FILE__}, and @code{__BASE_FILE__}. +@opindex Wfree-labels +@opindex Wno-free-labels +@item -Wfree-labels @r{(C and Objective-C only)} +Warn if a label is applied to a non-statement, or occurs at the end of a +compound statement. Such labels are allowed by C23 and later dialects +of C, and are available as a GCC extension in all other dialects. + +This warning is also enabled by @option{-Wc11-c23-compat}. It is turned +into an error if building for a C version before C23 by +@option{-pedantic-errors}. + @opindex Wheader-guard @item -Wheader-guard Warn if a valid preprocessor header multiple inclusion guard has diff --git a/gcc/testsuite/gcc.dg/Wfree-labels-1.c b/gcc/testsuite/gcc.dg/Wfree-labels-1.c new file mode 100644 index 00000000000..a7f9ad4dd50 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-labels-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-Wfree-labels" } */ + +void +f (void) +{ + goto l; + l: /* { dg-warning "label at end of compound statement" } */ +} + +int +g (void) +{ + goto l; + l: + int x = 0; /* { dg-warning "a label can only be part of a statement" } */ + return x; +} diff --git a/gcc/testsuite/gcc.dg/Wfree-labels-2.c b/gcc/testsuite/gcc.dg/Wfree-labels-2.c new file mode 100644 index 00000000000..56b1fb0aeba --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-labels-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic -Wno-free-labels" } */ + +void +f (void) +{ + goto l; + l: +} + +int +g (void) +{ + goto l; + l: + int x = 0; + return x; +} diff --git a/gcc/testsuite/gcc.dg/Wfree-labels-3.c b/gcc/testsuite/gcc.dg/Wfree-labels-3.c new file mode 100644 index 00000000000..c9365977dbb --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wfree-labels-3.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-Wc11-c23-compat -Wno-free-labels" } */ + +void +f (void) +{ + goto l; + l: +} + +int +g (void) +{ + goto l; + l: + int x = 0; + return x; +} base-commit: 5f71122e9d83b63d5c572079ebb1df6eba2e4314