On Wed, Feb 12, 2025 at 08:27:37PM -0500, Lewis Hyatt wrote: > Hello- > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118838 > > This patch addresses the issue mentioned in the PR (another instance of > _Pragma string location issues). bootstrap + regtest all languages on > aarch64 looks good. Is it OK please for now or for stage 1? Note, it is not > a regression, since this never worked in C or C++ frontends; but on the > other hand, r15-4505 for GCC 15 fixed some related issues, so it could be > nice if this one gets in along with it. Thanks! > > -Lewis > > -- >8 -- > > The warning for -Wunknown-pragmas is issued at the location provided by > libcpp to the def_pragma() callback. This location is > cpp_reader::directive_line, which is a location for the start of the line > only; it is also not a valid location in case the unknown pragma was lexed > from a _Pragma string. These factors make it impossible to suppress > -Wunknown-pragmas via _Pragma("GCC diagnostic...") directives on the same > source line, as in the PR and the test case. Address that by issuing the > warning at a better location returned by cpp_get_diagnostic_override_loc(). > libcpp already maintains this location to handle _Pragma-related diagnostics > internally; it was needed also to make a publicly accessible version of it. > > gcc/c-family/ChangeLog: > > PR c/118838 > * c-lex.cc (cb_def_pragma): Call cpp_get_diagnostic_override_loc() > to get a valid location at which to issue -Wunknown-pragmas, in case > it was triggered from a _Pragma. > > libcpp/ChangeLog: > > PR c/118838 > * errors.cc (cpp_get_diagnostic_override_loc): New function. > * include/cpplib.h (cpp_get_diagnostic_override_loc): Declare. > > gcc/testsuite/ChangeLog: > > PR c/118838 > * c-c++-common/cpp/pragma-diagnostic-loc-2.c: New test. > * g++.dg/gomp/macro-4.C: Adjust expected output. > * gcc.dg/gomp/macro-4.c: Likewise. > * gcc.dg/cpp/Wunknown-pragmas-1.c: Likewise. > --- > libcpp/errors.cc | 10 +++++++++ > libcpp/include/cpplib.h | 5 +++++ > gcc/c-family/c-lex.cc | 7 +++++- > .../cpp/pragma-diagnostic-loc-2.c | 15 +++++++++++++ > gcc/testsuite/g++.dg/gomp/macro-4.C | 8 +++---- > gcc/testsuite/gcc.dg/cpp/Wunknown-pragmas-1.c | 22 +++++++++++-------- > gcc/testsuite/gcc.dg/gomp/macro-4.c | 8 +++---- > 7 files changed, 57 insertions(+), 18 deletions(-) > create mode 100644 gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c > > diff --git a/libcpp/errors.cc b/libcpp/errors.cc > index 9621c4b66ea..d9efb6acd30 100644 > --- a/libcpp/errors.cc > +++ b/libcpp/errors.cc > @@ -52,6 +52,16 @@ cpp_diagnostic_get_current_location (cpp_reader *pfile) > } > } > > +/* Sometimes a diagnostic needs to be generated before libcpp has been able > + to generate a valid location for the current token; in that case, the > + non-zero location returned by this function is the preferred one to use. > */ > + > +location_t > +cpp_get_diagnostic_override_loc (const cpp_reader *pfile) > +{ > + return pfile->diagnostic_override_loc; > +} > + > /* Print a diagnostic at the given location. */ > > ATTRIBUTE_CPP_PPDIAG (5, 0) > diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h > index 90aa3160ebf..04d4621da3c 100644 > --- a/libcpp/include/cpplib.h > +++ b/libcpp/include/cpplib.h > @@ -1168,6 +1168,11 @@ extern const char *cpp_probe_header_unit (cpp_reader > *, const char *file, > extern const char *cpp_get_narrow_charset_name (cpp_reader *) ATTRIBUTE_PURE; > extern const char *cpp_get_wide_charset_name (cpp_reader *) ATTRIBUTE_PURE; > > +/* Sometimes a diagnostic needs to be generated before libcpp has been able > + to generate a valid location for the current token; in that case, the > + non-zero location returned by this function is the preferred one to use. > */
I don't love duplicating the comment like this, it's going to get out of sync. > +extern location_t cpp_get_diagnostic_override_loc (const cpp_reader *); > + > /* This function reads the file, but does not start preprocessing. It > returns the name of the original file; this is the same as the > input file, except for preprocessed input. This will generate at > diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc > index e450c9a57f0..df84020de62 100644 > --- a/gcc/c-family/c-lex.cc > +++ b/gcc/c-family/c-lex.cc > @@ -248,7 +248,12 @@ cb_def_pragma (cpp_reader *pfile, location_t loc) > { > const unsigned char *space, *name; > const cpp_token *s; > - location_t fe_loc = loc; > + > + /* If we are processing a _Pragma, LOC is not a valid location, but > libcpp > + will provide a good location via this function instead. */ > + location_t fe_loc = cpp_get_diagnostic_override_loc (pfile); > + if (!fe_loc) I think checking == UNKNOWN_LOCATION is clearer. > + fe_loc = loc; > > space = name = (const unsigned char *) ""; > > diff --git a/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c > b/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c > new file mode 100644 > index 00000000000..e7e8cf23759 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/cpp/pragma-diagnostic-loc-2.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-Wunknown-pragmas" } */ > + > +/* PR 118838 */ Usually this would be the first line and also mention "c/". But those comments are details. I think the patch is OK for GCC 16. Thanks, Marek