[COMMITTED,gcc12] c: Fix location for _Pragma tokens [PR97498]
Commit Message
Hello-
This backport from r13-1596 to GCC 12 has been committed after
pre-approval. This was a straightforward cherry-pick from master with no
adjustments needed. I would like to note that subsequent to r13-1596, Thomas
made a few commits to the libgomp testsuite to test for new diagnostic notes
output after this patch; I have not backported these since I was not sure if
that would be appropriate. I did verify that the libgomp testsuite changes
work OK as-is on this branch, i.e. do not introduce any new failures,
including with offloading enabled.
-Lewis
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.
(cherry picked from commit 0587cef3d7962a8b0f44779589ba2920dd3d71e5)
Comments
On Mon, Aug 01, 2022 at 07:15:48PM -0400, Lewis Hyatt wrote:
> Hello-
>
> This backport from r13-1596 to GCC 12 has been committed after
> pre-approval. This was a straightforward cherry-pick from master with no
> adjustments needed. I would like to note that subsequent to r13-1596, Thomas
> made a few commits to the libgomp testsuite to test for new diagnostic notes
> output after this patch; I have not backported these since I was not sure if
> that would be appropriate. I did verify that the libgomp testsuite changes
> work OK as-is on this branch, i.e. do not introduce any new failures,
> including with offloading enabled.
I have done the same for GCC 11 and 10 branches, patches attached. Thanks!
-Lewis
[GCC10] 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.c (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.c (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.
* gcc.dg/pragma-message.c: Adapt for improved warning locations.
(cherry picked from commit 0587cef3d7962a8b0f44779589ba2920dd3d71e5)
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 2d347ad927c..b2c7a74b464 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -12328,6 +12328,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/pr97498.c b/gcc/testsuite/c-c++-common/pr97498.c
new file mode 100644
index 00000000000..f5fa420415b
--- /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 2f44b617710..1b7cf09de0a 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")
diff --git a/libcpp/directives.c b/libcpp/directives.c
index cab9aad64d2..0d8545a7df9 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -1887,6 +1887,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in,
maxcount = 50;
toks = XNEWVEC (cpp_token, maxcount);
toks[0] = pfile->directive_result;
+ toks[0].src_loc = expansion_loc;
do
{
[GCC11] 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.c (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.c (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.
* gcc.dg/pragma-message.c: Adapt for improved warning locations.
(cherry picked from commit 0587cef3d7962a8b0f44779589ba2920dd3d71e5)
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 7690977f6b8..407c22afa6f 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -12289,6 +12289,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/pr97498.c b/gcc/testsuite/c-c++-common/pr97498.c
new file mode 100644
index 00000000000..f5fa420415b
--- /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 2f44b617710..1b7cf09de0a 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")
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 347ddb8b1e1..d764ddfa38e 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -1905,6 +1905,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in,
maxcount = 50;
toks = XNEWVEC (cpp_token, maxcount);
toks[0] = pfile->directive_result;
+ toks[0].src_loc = expansion_loc;
do
{
@@ -12378,6 +12378,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);
@@ -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
@@ -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
new file mode 100644
@@ -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" } */
@@ -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")
@@ -1930,6 +1930,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in,
maxcount = 50;
toks = XNEWVEC (cpp_token, maxcount);
toks[0] = pfile->directive_result;
+ toks[0].src_loc = expansion_loc;
do
{
@@ -12,7 +12,7 @@
const int n = 100;
-#define DO_PRAGMA(x) _Pragma (#x)
+#define DO_PRAGMA(x) _Pragma (#x) /* { dg-line pragma_loc } */
#define check_reduction(gwv_par, gwv_loop) \
{ \
@@ -46,7 +46,7 @@ main (void)
/* Nvptx targets require a vector_length or 32 in to allow spinlocks with
gangs. */
check_reduction (num_workers (nw) vector_length (vl), worker);
- /* { dg-warning "region is vector partitioned but does not contain vector partitioned code" "" { target *-*-* } .-1 } */
+ /* { dg-warning "region is vector partitioned but does not contain vector partitioned code" "test1" { target *-*-* } pragma_loc } */
check_reduction (vector_length (vl), vector);
check_reduction (num_gangs (ng) num_workers (nw) vector_length (vl), gang
worker vector);
@@ -17,7 +17,7 @@ int a1[n], a2[n];
void name () \
{ \
long i, j, t1, t2, t3; /* { dg-line vars } */ \
- _Pragma(outer) \
+ _Pragma(outer) /* { dg-line outer } */ \
for (i = 0; i < n; i++) \
{ \
t1 = 0; \
@@ -40,44 +40,44 @@ int a1[n], a2[n];
gentest (test1, "acc parallel loop gang vector_length (128) firstprivate (t1, t2)",
"acc loop vector reduction(+:t1) reduction(-:t2)")
-/* { dg-warning {'t1' is used uninitialized} {} { target *-*-* } .-1 }
+/* { dg-warning {'t1' is used uninitialized} {} { target *-*-* } outer }
{ dg-note {'t1' was declared here} {} { target *-*-* } vars }
{ dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-4 }
TODO See PR101551 for 'offloading_enabled' differences. */
-/* { dg-warning {'t2' is used uninitialized} {} { target *-*-* } .-5 }
+/* { dg-warning {'t2' is used uninitialized} {} { target *-*-* } outer }
{ dg-note {'t2' was declared here} {} { target *-*-* } vars }
{ DUP_dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-8 }
TODO See PR101551 for 'offloading_enabled' differences. */
gentest (test2, "acc parallel loop gang vector_length (128) firstprivate (t1, t2)",
"acc loop worker vector reduction(+:t1) reduction(-:t2)")
-/* { dg-warning {'t1' is used uninitialized} {} { target *-*-* } .-1 }
+/* { DUPdg-warning {'t1' is used uninitialized} {} { target *-*-* } outer }
{ DUP_dg-note {'t1' was declared here} {} { target *-*-* } vars }
{ dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-4 }
TODO See PR101551 for 'offloading_enabled' differences. */
-/* { dg-warning {'t2' is used uninitialized} {} { target *-*-* } .-5 }
+/* { DUPdg-warning {'t2' is used uninitialized} {} { target *-*-* } outer }
{ DUP_dg-note {'t2' was declared here} {} { target *-*-* } vars }
{ DUP_dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-8 }
TODO See PR101551 for 'offloading_enabled' differences. */
gentest (test3, "acc parallel loop gang worker vector_length (128) firstprivate (t1, t2)",
"acc loop vector reduction(+:t1) reduction(-:t2)")
-/* { dg-warning {'t1' is used uninitialized} {} { target *-*-* } .-1 }
+/* { DUPdg-warning {'t1' is used uninitialized} {} { target *-*-* } outer }
{ DUP_dg-note {'t1' was declared here} {} { target *-*-* } vars }
{ dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-4 }
TODO See PR101551 for 'offloading_enabled' differences. */
-/* { dg-warning {'t2' is used uninitialized} {} { target *-*-* } .-5 }
+/* { DUPdg-warning {'t2' is used uninitialized} {} { target *-*-* } outer }
{ DUP_dg-note {'t2' was declared here} {} { target *-*-* } vars }
{ DUP_dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-8 }
TODO See PR101551 for 'offloading_enabled' differences. */
gentest (test4, "acc parallel loop firstprivate (t1, t2)",
"acc loop reduction(+:t1) reduction(-:t2)")
-/* { dg-warning {'t1' is used uninitialized} {} { target *-*-* } .-1 }
+/* { DUPdg-warning {'t1' is used uninitialized} {} { target *-*-* } outer }
{ DUP_dg-note {'t1' was declared here} {} { target *-*-* } vars }
{ dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-4 }
TODO See PR101551 for 'offloading_enabled' differences. */
-/* { dg-warning {'t2' is used uninitialized} {} { target *-*-* } .-5 }
+/* { DUPdg-warning {'t2' is used uninitialized} {} { target *-*-* } outer }
{ DUP_dg-note {'t2' was declared here} {} { target *-*-* } vars }
{ DUP_dg-note {in expansion of macro 'gentest'} {} { target { ! offloading_enabled } } .-8 }
TODO See PR101551 for 'offloading_enabled' differences. */