On Tue, Jun 4, 2024 at 7:54 AM Jason Merrill <ja...@redhat.com> wrote: > > On 3/14/24 04:01, Ken Matsui wrote: > > On Sat, Mar 2, 2024 at 5:04 AM Ken Matsui <kmat...@gcc.gnu.org> wrote: > >> > >> This patch adds a warning switch for "#pragma once in main file". The > >> warning option name is Wpragma-once-outside-header, which is the same > >> as Clang. > > > > Ping. > > > >> > >> PR preprocessor/89808 > >> > >> gcc/c-family/ChangeLog: > >> > >> * c-opts.cc (c_common_handle_option): Handle > >> OPT_Wpragma_once_outside_header. > >> * c.opt (Wpragma_once_outside_header): Define new option. > >> > >> gcc/ChangeLog: > >> > >> * doc/invoke.texi (Warning Options): Document > >> -Wno-pragma-once-outside-header. > >> > >> libcpp/ChangeLog: > >> > >> * include/cpplib.h (struct cpp_options): Define > >> cpp_warn_pragma_once_outside_header. > >> * directives.cc (do_pragma_once): Use > >> cpp_warn_pragma_once_outside_header. > >> * init.cc (cpp_create_reader): Handle > >> cpp_warn_pragma_once_outside_header. > >> > >> gcc/testsuite/ChangeLog: > >> > >> * g++.dg/Wpragma-once-outside-header.C: New test. > > Please drop this file, keeping the duplicate in the warn subdirectory. > > >> * g++.dg/warn/Wno-pragma-once-outside-header.C: New test. > >> * g++.dg/warn/Wpragma-once-outside-header.C: New test. > >> > >> Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org> > >> --- > >> gcc/c-family/c-opts.cc | 9 +++++++++ > >> gcc/c-family/c.opt | 4 ++++ > >> gcc/doc/invoke.texi | 10 ++++++++-- > >> gcc/testsuite/g++.dg/Wpragma-once-outside-header.C | 5 +++++ > >> .../g++.dg/warn/Wno-pragma-once-outside-header.C | 5 +++++ > >> .../g++.dg/warn/Wpragma-once-outside-header.C | 5 +++++ > >> libcpp/directives.cc | 8 ++++++-- > >> libcpp/include/cpplib.h | 4 ++++ > >> libcpp/init.cc | 1 + > >> 9 files changed, 47 insertions(+), 4 deletions(-) > >> create mode 100644 gcc/testsuite/g++.dg/Wpragma-once-outside-header.C > >> create mode 100644 > >> gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C > >> create mode 100644 > >> gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C > >> > >> diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc > >> index be3058dca63..4edd8c6c515 100644 > >> --- a/gcc/c-family/c-opts.cc > >> +++ b/gcc/c-family/c-opts.cc > >> @@ -430,6 +430,15 @@ c_common_handle_option (size_t scode, const char > >> *arg, HOST_WIDE_INT value, > >> cpp_opts->warn_num_sign_change = value; > >> break; > >> > >> + case OPT_Wpragma_once_outside_header: > >> + if (value == 0) > >> + cpp_opts->cpp_warn_pragma_once_outside_header = 0; > >> + else if (kind == DK_ERROR) > >> + cpp_opts->cpp_warn_pragma_once_outside_header = 2; > >> + else > >> + cpp_opts->cpp_warn_pragma_once_outside_header = 1; > >> + break; > > Rather than encode the -Werror this way... > > >> case OPT_Wunknown_pragmas: > >> /* Set to greater than 1, so that even unknown pragmas in > >> system headers will be warned about. */ > >> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt > >> index b7a4a1a68e3..6841a5a5e81 100644 > >> --- a/gcc/c-family/c.opt > >> +++ b/gcc/c-family/c.opt > >> @@ -1180,6 +1180,10 @@ Wpragmas > >> C ObjC C++ ObjC++ Var(warn_pragmas) Init(1) Warning > >> Warn about misuses of pragmas. > >> > >> +Wpragma-once-outside-header > >> +C ObjC C++ ObjC++ Var(warn_pragma_once_outside_header) Init(1) Warning > >> +Warn about #pragma once outside of a header. > >> + > >> Wprio-ctor-dtor > >> C ObjC C++ ObjC++ Var(warn_prio_ctor_dtor) Init(1) Warning > >> Warn if constructor or destructors with priorities from 0 to 100 are > >> used. > >> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > >> index bdf05be387d..eeb8954bcdf 100644 > >> --- a/gcc/doc/invoke.texi > >> +++ b/gcc/doc/invoke.texi > >> @@ -391,8 +391,8 @@ Objective-C and Objective-C++ Dialects}. > >> -Wpacked -Wno-packed-bitfield-compat -Wpacked-not-aligned -Wpadded > >> -Wparentheses -Wno-pedantic-ms-format > >> -Wpointer-arith -Wno-pointer-compare -Wno-pointer-to-int-cast > >> --Wno-pragmas -Wno-prio-ctor-dtor -Wredundant-decls > >> --Wrestrict -Wno-return-local-addr -Wreturn-type > >> +-Wno-pragmas -Wno-pragma-once-outside-header -Wno-prio-ctor-dtor > >> +-Wredundant-decls -Wrestrict -Wno-return-local-addr -Wreturn-type > >> -Wno-scalar-storage-order -Wsequence-point > >> -Wshadow -Wshadow=global -Wshadow=local -Wshadow=compatible-local > >> -Wno-shadow-ivar > >> @@ -7955,6 +7955,12 @@ Do not warn about misuses of pragmas, such as > >> incorrect parameters, > >> invalid syntax, or conflicts between pragmas. See also > >> @option{-Wunknown-pragmas}. > >> > >> +@opindex Wno-pragma-once-outside-header > >> +@opindex Wpragma-once-outside-header > >> +@item -Wno-pragma-once-outside-header > >> +Do not warn when @code{#pragma once} is used in a file that is not a > >> header > >> +file, such as a main file. > >> + > >> @opindex Wno-prio-ctor-dtor > >> @opindex Wprio-ctor-dtor > >> @item -Wno-prio-ctor-dtor > >> diff --git a/gcc/testsuite/g++.dg/Wpragma-once-outside-header.C > >> b/gcc/testsuite/g++.dg/Wpragma-once-outside-header.C > >> new file mode 100644 > >> index 00000000000..678bd4e7626 > >> --- /dev/null > >> +++ b/gcc/testsuite/g++.dg/Wpragma-once-outside-header.C > >> @@ -0,0 +1,5 @@ > >> +/* { dg-do assemble } */ > >> +/* { dg-options "-Werror=pragma-once-outside-header" } */ > >> + > >> +#pragma once // { dg-error "#pragma once in main file" } > >> +int main() {} > >> diff --git a/gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C > >> b/gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C > >> new file mode 100644 > >> index 00000000000..b5be4d25a9d > >> --- /dev/null > >> +++ b/gcc/testsuite/g++.dg/warn/Wno-pragma-once-outside-header.C > >> @@ -0,0 +1,5 @@ > >> +// { dg-do assemble } > >> +// { dg-options "-Wno-pragma-once-outside-header" } > >> + > >> +#pragma once > >> +int main() {} > >> diff --git a/gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C > >> b/gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C > >> new file mode 100644 > >> index 00000000000..ae958d3beb8 > >> --- /dev/null > >> +++ b/gcc/testsuite/g++.dg/warn/Wpragma-once-outside-header.C > >> @@ -0,0 +1,5 @@ > >> +// { dg-do assemble } > >> +// { dg-options "-Werror=pragma-once-outside-header" } > >> + > >> +#pragma once // { dg-error "#pragma once in main file" } > >> +int main() {} > >> diff --git a/libcpp/directives.cc b/libcpp/directives.cc > >> index 479f8c716e8..b6121a459f8 100644 > >> --- a/libcpp/directives.cc > >> +++ b/libcpp/directives.cc > >> @@ -1588,8 +1588,12 @@ do_pragma (cpp_reader *pfile) > >> static void > >> do_pragma_once (cpp_reader *pfile) > >> { > >> - if (_cpp_in_main_source_file (pfile)) > >> - cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file"); > >> + const unsigned char warn_level = > >> + CPP_OPTION (pfile, cpp_warn_pragma_once_outside_header); > >> + > >> + if (warn_level && _cpp_in_main_source_file (pfile)) > >> + cpp_error (pfile, (warn_level == 1 ? CPP_DL_WARNING : CPP_DL_ERROR), > >> + "#pragma once in main file"); > > ...it would seem better to use cpp_warning and add a cpp_warning_reason > for this diagnostic, so the normal -Werror handling (including #pragma > GCC diagnostic) takes care of it?
Thank you for your review! I'll soon update this patch. > > Jason >