From 0587cef3d7962a8b0f44779589ba2920dd3d71e5 Mon Sep 17 00:00:00 2001 From: Lewis Hyatt Date: Sat, 9 Jul 2022 16:12:21 -0400 Subject: c: Fix location for _Pragma tokens [PR97498] The handling of #pragma GCC diagnostic uses input_location, which is not always as precise as needed; in particular the relative location of some tokens and a _Pragma directive will crucially determine whether a given diagnostic is enabled or suppressed in the desired way. PR97498 shows how the C frontend ends up with input_location pointing to the beginning of the line containing a _Pragma() directive, resulting in the wrong behavior if the diagnostic to be modified pertains to some tokens found earlier on the same line. This patch fixes that by addressing two issues: a) libcpp was not assigning a valid location to the CPP_PRAGMA token generated by the _Pragma directive. b) C frontend was not setting input_location to something reasonable. With this change, the C frontend is able to change input_location to point to the _Pragma token as needed. This is just a two-line fix (one for each of a) and b)), the testsuite changes were needed only because the location on the tested warnings has been somewhat improved, so the tests need to look for the new locations. gcc/c/ChangeLog: PR preprocessor/97498 * c-parser.cc (c_parser_pragma): Set input_location to the location of the pragma, rather than the start of the line. libcpp/ChangeLog: PR preprocessor/97498 * directives.cc (destringize_and_run): Override the location of the CPP_PRAGMA token from a _Pragma directive to the location of the expansion point, as is done for the tokens lexed from it. gcc/testsuite/ChangeLog: PR preprocessor/97498 * c-c++-common/pr97498.c: New test. * c-c++-common/gomp/pragma-3.c: Adapt for improved warning locations. * c-c++-common/gomp/pragma-5.c: Likewise. * gcc.dg/pragma-message.c: Likewise. libgomp/ChangeLog: * testsuite/libgomp.oacc-c-c++-common/reduction-5.c: Adapt for improved warning locations. * testsuite/libgomp.oacc-c-c++-common/vred2d-128.c: Likewise. --- gcc/c/c-parser.cc | 1 + gcc/testsuite/c-c++-common/gomp/pragma-3.c | 5 +++-- gcc/testsuite/c-c++-common/gomp/pragma-5.c | 5 +++-- gcc/testsuite/c-c++-common/pr97498.c | 4 ++++ gcc/testsuite/gcc.dg/pragma-message.c | 8 +++++--- 5 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr97498.c (limited to 'gcc') diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 9c02141..92049d1 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -12397,6 +12397,7 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p) unsigned int id; const char *construct = NULL; + input_location = c_parser_peek_token (parser)->location; id = c_parser_peek_token (parser)->pragma_kind; gcc_assert (id != PRAGMA_NONE); diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-3.c b/gcc/testsuite/c-c++-common/gomp/pragma-3.c index c1dee1b..ae18e9b 100644 --- a/gcc/testsuite/c-c++-common/gomp/pragma-3.c +++ b/gcc/testsuite/c-c++-common/gomp/pragma-3.c @@ -1,13 +1,14 @@ /* { dg-additional-options "-fdump-tree-original" } */ /* PR preprocessor/103165 */ -#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)") +#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)") /* { dg-line inner_location } */ #define outer(...) inner(__VA_ARGS__) void f (void) { - const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ + const char *str = outer(inner(1,2)); + /* { dg-warning "'pragma omp error' encountered: Test" "inner expansion" { target *-*-* } inner_location } */ } #if 0 diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-5.c b/gcc/testsuite/c-c++-common/gomp/pragma-5.c index af54b68..8124f70 100644 --- a/gcc/testsuite/c-c++-common/gomp/pragma-5.c +++ b/gcc/testsuite/c-c++-common/gomp/pragma-5.c @@ -1,13 +1,14 @@ /* { dg-additional-options "-fdump-tree-original" } */ /* PR preprocessor/103165 */ -#define inner(...) #__VA_ARGS__ ; _Pragma ( " omp error severity (warning) message (\"Test\") at(compilation)" ) +#define inner(...) #__VA_ARGS__ ; _Pragma ( " omp error severity (warning) message (\"Test\") at(compilation)" ) /* { dg-line inner_location } */ #define outer(...) inner(__VA_ARGS__) void f (void) { - const char *str = outer(inner(1,2)); /* { dg-warning "'pragma omp error' encountered: Test" } */ + const char *str = outer(inner(1,2)); + /* { dg-warning "'pragma omp error' encountered: Test" "inner expansion" { target *-*-* } inner_location } */ } #if 0 diff --git a/gcc/testsuite/c-c++-common/pr97498.c b/gcc/testsuite/c-c++-common/pr97498.c new file mode 100644 index 0000000..f5fa420 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr97498.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Wunused-function" } */ +#pragma GCC diagnostic ignored "-Wunused-function" +static void f() {} _Pragma("GCC diagnostic error \"-Wunused-function\"") /* { dg-bogus "-Wunused-function" } */ diff --git a/gcc/testsuite/gcc.dg/pragma-message.c b/gcc/testsuite/gcc.dg/pragma-message.c index 2f44b61..1b7cf09 100644 --- a/gcc/testsuite/gcc.dg/pragma-message.c +++ b/gcc/testsuite/gcc.dg/pragma-message.c @@ -42,9 +42,11 @@ #pragma message ("Okay " THREE) /* { dg-message "Okay 3" } */ /* Create a TODO() that prints a message on compilation. */ -#define DO_PRAGMA(x) _Pragma (#x) -#define TODO(x) DO_PRAGMA(message ("TODO - " #x)) -TODO(Okay 4) /* { dg-message "TODO - Okay 4" } */ +#define DO_PRAGMA(x) _Pragma (#x) /* { dg-line pragma_loc1 } */ +#define TODO(x) DO_PRAGMA(message ("TODO - " #x)) /* { dg-line pragma_loc2 } */ +TODO(Okay 4) /* { dg-message "in expansion of macro 'TODO'" } */ +/* { dg-message "TODO - Okay 4" "test4.1" { target *-*-* } pragma_loc1 } */ +/* { dg-message "in expansion of macro 'DO_PRAGMA'" "test4.2" { target *-*-* } pragma_loc2 } */ #if 0 #pragma message ("Not printed") -- cgit v1.1