diff options
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pragma-3.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pragma-4.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pragma-5.c | 20 | ||||
-rw-r--r-- | libcpp/internal.h | 3 | ||||
-rw-r--r-- | 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 0000000..c1dee1b --- /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 0000000..419c4ac --- /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 0000000..af54b68 --- /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 0ce0246..b72d616 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 b2f797c..95e5b8b 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 |