public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5454] libcpp: Fix _Pragma stringification [PR103165]
@ 2021-11-22 21:34 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2021-11-22 21:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a6e0d593707ae44dec0bdf2bcdc4f539050b46db

commit r12-5454-ga6e0d593707ae44dec0bdf2bcdc4f539050b46db
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Nov 22 22:29:20 2021 +0100

    libcpp: Fix _Pragma stringification [PR103165]
    
    As the testcase show, sometimes _Pragma is turned into CPP_PRAGMA
    .. CPP_PRAGMA_EOL tokens, even when it might still need to be
    stringized later on.  We are then ICEing because we don't handle
    stringification of CPP_PRAGMA or CPP_PRAGMA_EOL, but trying to
    reconstruct the exact tokens with exact spacing after it has been
    lowered is very hard.  So, instead this patch ensures we don't
    lower _Pragma during expand_arg calls, but only later when
    cpp_get_token_1 is called outside of expand_arg.
    
    2021-11-22  Jakub Jelinek  <jakub@redhat.com>
                Tobias Burnus  <tobias@codesourcery.com>
    
            PR preprocessor/103165
    libcpp/
            * internal.h (struct lexer_state): Add ignore__Pragma field.
            * macro.c (builtin_macro): Don't interpret _Pragma if
            pfile->state.ignore__Pragma.
            (expand_arg): Temporarily set pfile->state.ignore__Pragma to 1.
    gcc/testsuite/
            * c-c++-common/gomp/pragma-3.c: New test.
            * c-c++-common/gomp/pragma-4.c: New test.
            * c-c++-common/gomp/pragma-5.c: New test.
    
    Co-Authored-By: Tobias Burnus <tobias@codesourcery.com>

Diff:
---
 gcc/testsuite/c-c++-common/gomp/pragma-3.c | 20 ++++++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/pragma-4.c | 20 ++++++++++++++++++++
 gcc/testsuite/c-c++-common/gomp/pragma-5.c | 20 ++++++++++++++++++++
 libcpp/internal.h                          |  3 +++
 libcpp/macro.c                             | 11 +++++++++--
 5 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-3.c b/gcc/testsuite/c-c++-common/gomp/pragma-3.c
new file mode 100644
index 00000000000..c1dee1bcc62
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-3.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-fdump-tree-original" }  */
+/* PR preprocessor/103165  */
+
+#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)")
+#define outer(...) inner(__VA_ARGS__)
+
+void
+f (void)
+{
+  const char *str = outer(inner(1,2));  /* { dg-warning "'pragma omp error' encountered: Test" } */
+}
+
+#if 0
+After preprocessing, the expected result are the following three lines:
+     const char *str = "\"1,2\" ; _Pragma(\"omp error severity(warning) message (\\\"Test\\\") at(compilation)\")" ;
+#pragma omp error severity(warning) message ("Test") at(compilation)
+                                     ;
+#endif
+
+/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma\\(\\\\\"omp error severity\\(warning\\) message \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\"\\)\";" "original" } }  */
diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-4.c b/gcc/testsuite/c-c++-common/gomp/pragma-4.c
new file mode 100644
index 00000000000..419c4ac32f5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-4.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-fdump-tree-original -save-temps" }  */
+/* PR preprocessor/103165  */
+
+#define inner(...) #__VA_ARGS__ ; _Pragma("omp error severity(warning) message (\"Test\") at(compilation)")
+#define outer(...) inner(__VA_ARGS__)
+
+void
+f (void)
+{
+  const char *str = outer(inner(1,2));  /* { dg-warning "'pragma omp error' encountered: Test" } */
+}
+
+#if 0
+After preprocessing, the expected result are the following three lines:
+     const char *str = "\"1,2\" ; _Pragma(\"omp error severity(warning) message (\\\"Test\\\") at(compilation)\")" ;
+#pragma omp error severity(warning) message ("Test") at(compilation)
+                                     ;
+#endif
+
+/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma\\(\\\\\"omp error severity\\(warning\\) message \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\"\\)\";" "original" } }  */
diff --git a/gcc/testsuite/c-c++-common/gomp/pragma-5.c b/gcc/testsuite/c-c++-common/gomp/pragma-5.c
new file mode 100644
index 00000000000..af54b682789
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pragma-5.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-fdump-tree-original" }  */
+/* PR preprocessor/103165  */
+
+#define inner(...) #__VA_ARGS__ ; _Pragma   (	"   omp		error severity   (warning)	message (\"Test\") at(compilation)" )
+#define outer(...) inner(__VA_ARGS__)
+
+void
+f (void)
+{
+  const char *str = outer(inner(1,2));  /* { dg-warning "'pragma omp error' encountered: Test" } */
+}
+
+#if 0
+After preprocessing, the expected result are the following three lines:
+     const char *str = "\"1,2\" ; _Pragma ( \"   omp		error severity   (warning)	message (\\\"Test\\\") at(compilation)\" )" ;
+#pragma omp error severity(warning) message ("Test") at(compilation)
+                                     ;
+#endif
+
+/* { dg-final { scan-tree-dump "const char \\* str = \\(const char \\*\\) \"\\\\\"1,2\\\\\" ; _Pragma \\( \\\\\"   omp\\\\t\\\\terror severity   \\(warning\\)\\\\tmessage \\(\\\\\\\\\\\\\"Test\\\\\\\\\\\\\"\\) at\\(compilation\\)\\\\\" \\)\";" "original" } }  */
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 0ce0246c5a2..b72d6160564 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -287,6 +287,9 @@ struct lexer_state
 
   /* Nonzero if the deferred pragma being handled allows macro expansion.  */
   unsigned char pragma_allow_expansion;
+
+  /* Nonzero if _Pragma should not be interpreted.  */
+  unsigned char ignore__Pragma;
 };
 
 /* Special nodes - identifiers with predefined significance.  */
diff --git a/libcpp/macro.c b/libcpp/macro.c
index b2f797cae35..95e5b8be8d5 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -750,8 +750,10 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node,
   if (node->value.builtin == BT_PRAGMA)
     {
       /* Don't interpret _Pragma within directives.  The standard is
-         not clear on this, but to me this makes most sense.  */
-      if (pfile->state.in_directive)
+         not clear on this, but to me this makes most sense.
+         Similarly, don't interpret _Pragma inside expand_args, we might
+         need to stringize it later on.  */
+      if (pfile->state.in_directive || pfile->state.ignore__Pragma)
 	return 0;
 
       return _cpp_do__Pragma (pfile, loc);
@@ -2648,6 +2650,7 @@ expand_arg (cpp_reader *pfile, macro_arg *arg)
   size_t capacity;
   bool saved_warn_trad;
   bool track_macro_exp_p = CPP_OPTION (pfile, track_macro_expansion);
+  bool saved_ignore__Pragma;
 
   if (arg->count == 0
       || arg->expanded != NULL)
@@ -2670,6 +2673,9 @@ expand_arg (cpp_reader *pfile, macro_arg *arg)
     push_ptoken_context (pfile, NULL, NULL,
 			 arg->first, arg->count + 1);
 
+  saved_ignore__Pragma = pfile->state.ignore__Pragma;
+  pfile->state.ignore__Pragma = 1;
+
   for (;;)
     {
       const cpp_token *token;
@@ -2692,6 +2698,7 @@ expand_arg (cpp_reader *pfile, macro_arg *arg)
   _cpp_pop_context (pfile);
 
   CPP_WTRADITIONAL (pfile) = saved_warn_trad;
+  pfile->state.ignore__Pragma = saved_ignore__Pragma;
 }
 
 /* Returns the macro associated to the current context if we are in


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-22 21:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-22 21:34 [gcc r12-5454] libcpp: Fix _Pragma stringification [PR103165] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).