From: Jakub Jelinek <jakub@redhat.com>
To: Joseph Myers <joseph@codesourcery.com>
Cc: Tobias Burnus <tobias@codesourcery.com>,
gcc-patches <gcc-patches@gcc.gnu.org>
Subject: [PATCH] libcpp, v2: Fix _Pragma in #__VA_ARGS__ [PR103165]
Date: Mon, 22 Nov 2021 10:23:29 +0100 [thread overview]
Message-ID: <20211122092329.GI2646553@tucnak> (raw)
In-Reply-To: <alpine.DEB.2.22.394.2111182151390.1393807@digraph.polyomino.org.uk>
On Thu, Nov 18, 2021 at 09:55:52PM +0000, Joseph Myers wrote:
> On Thu, 18 Nov 2021, Jakub Jelinek via Gcc-patches wrote:
>
> > Are we handling the pragma at a wrong phase of preprocessing?
>
> I think that converting it to a single preprocessing token (rather than
> four separate preprocessing tokens), at a stage when stringizing might
> still occur, does indicate it's being processed too soon, and it would be
> better to do that only when it's known that the _Pragma preprocessing
> token will actually occur in the results of preprocessing the source file.
So like this? I.e. don't process _Pragma during expand_args where we can't
know what the macro will do with it?
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
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.
--- libcpp/internal.h.jj 2021-11-18 12:33:18.409679558 +0100
+++ libcpp/internal.h 2021-11-20 11:00:58.044399990 +0100
@@ -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. */
--- libcpp/macro.c.jj 2021-11-18 12:33:18.462678802 +0100
+++ libcpp/macro.c 2021-11-20 11:02:03.249478159 +0100
@@ -750,8 +750,10 @@ builtin_macro (cpp_reader *pfile, cpp_ha
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
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
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
_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
--- gcc/testsuite/c-c++-common/gomp/pragma-3.c.jj 2021-11-20 11:04:27.636429378 +0100
+++ gcc/testsuite/c-c++-common/gomp/pragma-3.c 2021-11-20 11:27:46.892589048 +0100
@@ -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" } } */
--- gcc/testsuite/c-c++-common/gomp/pragma-4.c.jj 2021-11-20 11:04:35.355319742 +0100
+++ gcc/testsuite/c-c++-common/gomp/pragma-4.c 2021-11-20 11:28:22.995078169 +0100
@@ -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" } } */
--- gcc/testsuite/c-c++-common/gomp/pragma-5.c.jj 2021-11-20 11:05:22.855645064 +0100
+++ gcc/testsuite/c-c++-common/gomp/pragma-5.c 2021-11-20 11:30:33.777227520 +0100
@@ -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" } } */
Jakub
next prev parent reply other threads:[~2021-11-22 9:23 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-10 20:12 [Patch] libcpp: " Tobias Burnus
2021-11-10 21:30 ` Joseph Myers
2021-11-18 11:24 ` Jakub Jelinek
2021-11-18 21:55 ` Joseph Myers
2021-11-22 9:23 ` Jakub Jelinek [this message]
2021-11-22 20:56 ` [PATCH] libcpp, v2: " Joseph Myers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211122092329.GI2646553@tucnak \
--to=jakub@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=joseph@codesourcery.com \
--cc=tobias@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).