https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66290
Lewis Hyatt <lhyatt at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |lhyatt at gcc dot gnu.org --- Comment #3 from Lewis Hyatt <lhyatt at gcc dot gnu.org> --- (https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598188.html) This testcase, hopefully soon to be committed as c-c++-common/pragma-diag-15.c: ------- /* { dg-do compile } */ /* { dg-additional-options "-Wunused-macros" } */ #define X /* { dg-warning "-:-Wunused-macros" {} { xfail c++ } } */ #pragma GCC diagnostic ignored "-Wunused-macros" ------- fails for C++, I believe it's the same thing pointed out in this PR. The reason is because of this in c_cpp_diagnostic() in c-common.cc: ------- if (done_lexing) richloc->set_range (0, input_location, SHOW_RANGE_WITH_CARET); ------- This warning is issued at the end of compilation, when done_lexing is true. However, input_location is not the right thing to use here, the location provided was remembered from the time the macro was lexed, and that's the one that needs to be used. The way it is now, input_location is at the end of the file, and so the macro is deemed to have been defined after the #pragma. I think this done_lexing concept was added to solve PR17964 many years ago. Does anyone know if it's still needed, are there still cases where libcpp can generate a diagnostic while C++ is parsing the already-lexed tokens? I have checked anyway, that the particular testcase on PR17964 passes if done_lexing is kept always false. I am trying the full testsuite now as well. If it can't be removed, then I think we need some way to tell c_cpp_diagnostic not to override a location for instances like this. Or paradoxically, we could set done_lexing=false in c_common_finish(), which would fix it as well. It fixes both my testcase, and the one in this original PR. Could be a reasonable fix, perhaps combined with renaming done_lexing to something more like override_libcpp_locations, but would be nice if it could just be removed as well. I can look into that but perhaps Joseph knows the details here already? diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index b9f01a65ed7..25a3c50de8e 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1283,6 +1283,7 @@ c_common_finish (void) /* For performance, avoid tearing down cpplib's internal structures with cpp_destroy (). */ + done_lexing = false; cpp_finish (parse_in, deps_stream); if (deps_stream && deps_stream != out_stream && deps_stream != stdout