]> git.ipfire.org Git - people/ms/gcc.git/commitdiff
c: Fix location for _Pragma tokens [PR97498]
authorLewis Hyatt <lhyatt@gmail.com>
Sat, 9 Jul 2022 20:12:21 +0000 (16:12 -0400)
committerLewis Hyatt <lhyatt@gmail.com>
Tue, 2 Aug 2022 22:25:48 +0000 (18:25 -0400)
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)

gcc/c/c-parser.c
gcc/testsuite/c-c++-common/pr97498.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pragma-message.c
libcpp/directives.c

index 7690977f6b8590599e54bb0e3b49afe21c322092..407c22afa6f4912cdc76a2d17e9e95cf702b4645 100644 (file)
@@ -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 (file)
index 0000000..f5fa420
--- /dev/null
@@ -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" } */
index 2f44b617710434238edb58a9142b1197d3c82b5a..1b7cf09de0aac144a77e8c67a196cb25dda7c4d4 100644 (file)
 #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")
index 347ddb8b1e15e1647453539c70dcb66f41df69f5..d764ddfa38e3a57a452f80432dc6d1aaa96f5aba 100644 (file)
@@ -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
        {