On Fri, Nov 15, 2024 at 9:13 AM Florian Weimer <[email protected]> wrote:
>
> 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).
I like this idea of having an option here, though I am not a fan of
the name of the option. When I saw `free`, I was not thinking of free
flowing or free radicals but rather free as price (beer).
I can't think of a good alternative though.
Note clang just uses Wc++23-extensions/Wc23-extensions (which is
similar to GCC's Wc11-c23-compat) and does not seem to have another
option to enable/disable this specific one.
Thanks,
Andrew Pinski
>
> 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
>