PR preprocessor/53469 - argument tokens of _Pragma miss virtual location
authorDodji Seketeli <dodji@redhat.com>
Mon, 27 Aug 2012 15:41:38 +0000 (15:41 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Mon, 27 Aug 2012 15:41:38 +0000 (17:41 +0200)
Consider this short test snippet:

-------------------------8-------------------
    #define STRINGIFY(x) #x
    #define TEST(x) \
      _Pragma(STRINGIFY(GCC diagnostic ignored "-Wunused-local-typedefs")) \
      typedef int myint;

    void bar ()
    {
      TEST(myint)
    }
-------------------------8-------------------

The _Pragma is effectively ignored, and compiling with
-Wunused-local-typedefs warns on the local typedef, even though the
pragma should have prevented the warning to be emitted.

This is because when the preprocessor sees the _Pragma operator and
then goes to handle the first token ('GCC' here) that makes up its
operands, it retains the spelling location of that token, not its
virtual location.

Later when diagnostic_report_diagnostic is called to emit the warning
(or ignore it because of the pragma), it compares the location of the
first operand of the pragma with the location of the unused location,
(by calling linemap_location_before_p) and that comparison fails
because in this case, both locations should be virtual.

This patch fixes the issue by teaching the pragma handling to use
virtual locations.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

libcpp/

PR preprocessor/53469
* directives.c (do_pragma): Use the virtual location for the
pragma token, instead of its spelling location.

gcc/testsuite/

PR preprocessor/53469
* gcc.dg/cpp/_Pragma7.c: New test case.

From-SVN: r190714

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/_Pragma7.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/directives.c

index fd5b3504baeaaeb3da4e4e807763b6a0fb4ef05d..d34a5c19882ae484b46d3186d90045f2432442c1 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-25  Dodji Seketeli  <dodji@redhat.com>
+
+       PR preprocessor/53469
+       * gcc.dg/cpp/_Pragma7.c: New test case.
+
 2012-08-27  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/54370
diff --git a/gcc/testsuite/gcc.dg/cpp/_Pragma7.c b/gcc/testsuite/gcc.dg/cpp/_Pragma7.c
new file mode 100644 (file)
index 0000000..a7a5b1b
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+  Origin: PR preprocessor/53469
+  { dg-do compile }
+ */
+
+#define STRINGIFY(x) #x
+#define TEST(x) \
+  _Pragma(STRINGIFY(GCC diagnostic ignored "-Wunused-local-typedefs")) \
+  typedef int myint;
+
+void bar ()
+{
+  TEST(myint)
+}
index e4da6ef3a107b622c16ba3af3ea01130a191b8ea..7c11fdd0b054e11f7475dedf9ed935b8e4725815 100644 (file)
@@ -1,3 +1,9 @@
+2012-05-25  Dodji Seketeli  <dodji@redhat.com>
+
+       PR preprocessor/53469
+       * directives.c (do_pragma): Use the virtual location for the
+       pragma token, instead of its spelling location.
+
 2012-08-14   Diego Novillo  <dnovillo@google.com>
 
        Merge from cxx-conversion branch.  Configury.
index e37b148da8775c6d949c47b13c9dee95841ff885..a8f2cc4317014f76a8d8b5bb2ef363a02a10237b 100644 (file)
@@ -1347,13 +1347,15 @@ static void
 do_pragma (cpp_reader *pfile)
 {
   const struct pragma_entry *p = NULL;
-  const cpp_token *token, *pragma_token = pfile->cur_token;
+  const cpp_token *token, *pragma_token;
+  source_location pragma_token_virt_loc = 0;
   cpp_token ns_token;
   unsigned int count = 1;
 
   pfile->state.prevent_expansion++;
 
-  token = cpp_get_token (pfile);
+  pragma_token = token = cpp_get_token_with_location (pfile,
+                                                     &pragma_token_virt_loc);
   ns_token = *token;
   if (token->type == CPP_NAME)
     {
@@ -1379,7 +1381,7 @@ do_pragma (cpp_reader *pfile)
     {
       if (p->is_deferred)
        {
-         pfile->directive_result.src_loc = pragma_token->src_loc;
+         pfile->directive_result.src_loc = pragma_token_virt_loc;
          pfile->directive_result.type = CPP_PRAGMA;
          pfile->directive_result.flags = pragma_token->flags;
          pfile->directive_result.val.pragma = p->u.ident;