summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-27 15:41:38 +0000
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-27 15:41:38 +0000
commit307df3d0df40235371cc6c02596d7f1badfc6c9e (patch)
tree3ced6ccbc7fcd596cb1529873cece3f5076eef5d
parentcf913247d2810eedf212b59feddcefec4aae91fe (diff)
downloadgcc-307df3d0df40235371cc6c02596d7f1badfc6c9e.tar.gz
PR preprocessor/53469 - argument tokens of _Pragma miss virtual location
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190714 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/_Pragma7.c14
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libcpp/directives.c8
4 files changed, 30 insertions, 3 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fd5b3504bae..d34a5c19882 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..a7a5b1bcb0b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/_Pragma7.c
@@ -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)
+}
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index e4da6ef3a10..7c11fdd0b05 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -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.
diff --git a/libcpp/directives.c b/libcpp/directives.c
index e37b148da87..a8f2cc43170 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -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;