Commit 765d600a by Jakub Jelinek

re PR preprocessor/34692 (Internal error with pragma in macro)

	PR preprocessor/34692
	* macro.c (collect_args): Add pragma_buff argument.  Push
	CPP_PRAGMA ... CPP_PRAGMA_EOL tokens to *pragma_buff, rather
	than into arguments.  Reset prevent_expansion and parsing_args
	state at CPP_PRAGMA_EOL/CPP_EOF.
	(funlike_invocation_p): Add pragma_buff argument, pass it through
	to collect_args.
	(enter_macro_context): Add result argument.  Adjust
	funlike_invocation_p caller.  Emit all deferred pragma tokens
	gathered during collect_args before the expansion, add a padding
	token.  Return 2 instead of 1 if any pragma tokens were prepended.
	(cpp_get_token): If enter_macro_context returns 2, don't return
	a padding token, instead cycle to grab CPP_PRAGMA token.
	* directives.c (_cpp_handle_directive): If was_parsing_args
	in deferred pragma, leave parsing_args and prevent_expansion as is.

	* gcc.dg/cpp/pr34692.c: New test.
	* gcc.dg/gomp/pr34692.c: New test.

From-SVN: r131819
parent 1525f2c3
2008-01-25 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/34692
* gcc.dg/cpp/pr34692.c: New test.
* gcc.dg/gomp/pr34692.c: New test.
2008-01-25 Olga Golovanevsky <olga@il.ibm.com> 2008-01-25 Olga Golovanevsky <olga@il.ibm.com>
* gcc.dg/struct/wo_prof_malloc_size_var.c: UnXFAIL. * gcc.dg/struct/wo_prof_malloc_size_var.c: UnXFAIL.
/* PR preprocessor/34692 */
/* { dg-do compile } */
/* { dg-options "" } */
/* { dg-require-visibility "" } */
/* { dg-final { scan-hidden "vara" } } */
/* { dg-final { scan-hidden "varb" } } */
/* { dg-final { scan-hidden "varc" } } */
/* { dg-final { scan-hidden "vard" } } */
/* { dg-final { scan-assembler "a b cde f g h" } } */
#define FOO(y, x) y #x
#define BAR(x) x
#define BAZ(x) x
FOO (const char *vara =,
a
#pragma GCC visibility push(hidden)
b
#pragma GCC visibility push(hidden)
cde f g h);
int varb = 6;
#pragma GCC visibility pop
#pragma GCC visibility pop
FOO (
BAR (
#pragma GCC visibility push(hidden)
const) char *varc =,);
#pragma GCC visibility pop
FOO (
BAR (
BAZ (
#pragma GCC visibility push(hidden)
#pragma GCC visibility push(hidden)
const) char) *vard =,);
#pragma GCC visibility pop
#pragma GCC visibility pop
/* PR preprocessor/34692 */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-gimple" } */
/* { dg-final { scan-tree-dump-times "#pragma omp parallel" 1 "gimple" } } */
/* { dg-final { scan-tree-dump-times "#pragma omp for private" 1 "gimple" } } */
void
foo (void)
{
int i;
#define FOO(y, x) y #x
#define BAR(x) x
#define BAZ(x) x
FOO (for (i = 0; i < 10; i++) { const char *vara =,
a
#define P parallel
#pragma omp P
#undef P
#define P for
b
#pragma omp P
#undef P
#define parallel atomic
cde f g h);
}
}
2008-01-25 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/34692
* macro.c (collect_args): Add pragma_buff argument. Push
CPP_PRAGMA ... CPP_PRAGMA_EOL tokens to *pragma_buff, rather
than into arguments. Reset prevent_expansion and parsing_args
state at CPP_PRAGMA_EOL/CPP_EOF.
(funlike_invocation_p): Add pragma_buff argument, pass it through
to collect_args.
(enter_macro_context): Add result argument. Adjust
funlike_invocation_p caller. Emit all deferred pragma tokens
gathered during collect_args before the expansion, add a padding
token. Return 2 instead of 1 if any pragma tokens were prepended.
(cpp_get_token): If enter_macro_context returns 2, don't return
a padding token, instead cycle to grab CPP_PRAGMA token.
* directives.c (_cpp_handle_directive): If was_parsing_args
in deferred pragma, leave parsing_args and prevent_expansion as is.
2008-01-22 Tom Tromey <tromey@redhat.com> 2008-01-22 Tom Tromey <tromey@redhat.com>
PR c++/34859: PR c++/34859
* macro.c (_cpp_create_definition): Handle __STDC_LIMIT_MACROS and * macro.c (_cpp_create_definition): Handle __STDC_LIMIT_MACROS and
__STDC_CONSTANT_MACROS. __STDC_CONSTANT_MACROS.
2008-01-07 Fred Fish <fnf@specifix.com> 2008-01-07 Fred Fish <fnf@specifix.com>
PR preprocessor/30363: PR preprocessor/30363
* traditional.c (replace_args_and_push): Add local variable * traditional.c (replace_args_and_push): Add local variable
cxtquote, calculate the replacement text size assuming a cxtquote, calculate the replacement text size assuming a
worst case of every input character quoted with backslash, worst case of every input character quoted with backslash,
...@@ -15,7 +33,7 @@ ...@@ -15,7 +33,7 @@
2008-01-03 Tom Tromey <tromey@redhat.com> 2008-01-03 Tom Tromey <tromey@redhat.com>
PR preprocessor/34602. PR preprocessor/34602
* directives.c (do_line): Don't try to spell EOF token. * directives.c (do_line): Don't try to spell EOF token.
(do_linemarker): Add comment. (do_linemarker): Add comment.
...@@ -26,7 +44,7 @@ ...@@ -26,7 +44,7 @@
2007-12-06 Tom Tromey <tromey@redhat.com> 2007-12-06 Tom Tromey <tromey@redhat.com>
PR c/29172: PR c/29172
* internal.h (struct cpp_reader) <file_hash_entries>: Changed * internal.h (struct cpp_reader) <file_hash_entries>: Changed
type. type.
<file_hash_entries_allocated, file_hash_entries_used>: Removed. <file_hash_entries_allocated, file_hash_entries_used>: Removed.
...@@ -43,13 +61,13 @@ ...@@ -43,13 +61,13 @@
2007-12-03 Tom Tromey <tromey@redhat.com> 2007-12-03 Tom Tromey <tromey@redhat.com>
PR preprocessor/34288: PR preprocessor/34288
* configure.ac, config.in: Rebuilt. * configure.ac, config.in: Rebuilt.
* configure.ac: Check for ssize_t. * configure.ac: Check for ssize_t.
2007-11-30 Tom Tromey <tromey@redhat.com> 2007-11-30 Tom Tromey <tromey@redhat.com>
PR preprocessor/32868: PR preprocessor/32868
* macro.c (_cpp_create_definition): Special case * macro.c (_cpp_create_definition): Special case
__STDC_FORMAT_MACROS. __STDC_FORMAT_MACROS.
...@@ -59,7 +77,7 @@ ...@@ -59,7 +77,7 @@
2007-11-11 Tom Tromey <tromey@redhat.com> 2007-11-11 Tom Tromey <tromey@redhat.com>
PR c++/17557: PR c++/17557
* include/cpplib.h (cpp_included_before): Declare. * include/cpplib.h (cpp_included_before): Declare.
* files.c (struct file_hash_entry) <location>: New field. * files.c (struct file_hash_entry) <location>: New field.
(_cpp_find_file): Initialize new field. (_cpp_find_file): Initialize new field.
...@@ -68,13 +86,13 @@ ...@@ -68,13 +86,13 @@
2007-11-01 Tom Tromey <tromey@redhat.com> 2007-11-01 Tom Tromey <tromey@redhat.com>
PR preprocessor/30805: PR preprocessor/30805
* macro.c (paste_tokens): Handle padding token. * macro.c (paste_tokens): Handle padding token.
(paste_tokens): Don't abort unless padding has PASTE_LEFT flag. (paste_tokens): Don't abort unless padding has PASTE_LEFT flag.
2007-10-31 Tom Tromey <tromey@redhat.com> 2007-10-31 Tom Tromey <tromey@redhat.com>
PR preprocessor/30786: PR preprocessor/30786
* macro.c (builtin_macro): Return result of _cpp_do__Pragma. * macro.c (builtin_macro): Return result of _cpp_do__Pragma.
* directives.c (_cpp_do__Pragma): Return error status. * directives.c (_cpp_do__Pragma): Return error status.
* internal.h (_cpp_do__Pragma): Update. * internal.h (_cpp_do__Pragma): Update.
...@@ -112,7 +130,7 @@ ...@@ -112,7 +130,7 @@
2007-08-18 Tom Tromey <tromey@redhat.com> 2007-08-18 Tom Tromey <tromey@redhat.com>
PR preprocessor/32974: PR preprocessor/32974
* directives.c (parse_include): Don't check for EOL when * directives.c (parse_include): Don't check for EOL when
processing #pragma dependency. processing #pragma dependency.
...@@ -227,7 +245,7 @@ ...@@ -227,7 +245,7 @@
2007-05-02 Tom Tromey <tromey@redhat.com> 2007-05-02 Tom Tromey <tromey@redhat.com>
PR preprocessor/28709: PR preprocessor/28709
* macro.c (paste_tokens): Remove PASTE_LEFT from the old lhs. * macro.c (paste_tokens): Remove PASTE_LEFT from the old lhs.
2007-03-30 Michael Meissner <michael.meissner@amd.com> 2007-03-30 Michael Meissner <michael.meissner@amd.com>
...@@ -247,13 +265,13 @@ ...@@ -247,13 +265,13 @@
2007-01-30 Tom Tromey <tromey@redhat.com> 2007-01-30 Tom Tromey <tromey@redhat.com>
PR preprocessor/30468: PR preprocessor/30468
* mkdeps.c (apply_vpath): Strip successive '/'s if we stripped * mkdeps.c (apply_vpath): Strip successive '/'s if we stripped
'./'. './'.
2007-01-30 Tom Tromey <tromey@redhat.com> 2007-01-30 Tom Tromey <tromey@redhat.com>
PR preprocessor/29966: PR preprocessor/29966
* macro.c (lex_expansion_token): Save and restore cpp_reader's * macro.c (lex_expansion_token): Save and restore cpp_reader's
cur_token. cur_token.
(_cpp_create_definition): Don't restore cur_token here. (_cpp_create_definition): Don't restore cur_token here.
...@@ -265,7 +283,7 @@ ...@@ -265,7 +283,7 @@
2007-01-12 Tom Tromey <tromey@redhat.com> 2007-01-12 Tom Tromey <tromey@redhat.com>
PR preprocessor/28227: PR preprocessor/28227
* directives.c (lex_macro_node): Added 'is_def_or_undef' * directives.c (lex_macro_node): Added 'is_def_or_undef'
argument. argument.
(do_define): Update. (do_define): Update.
...@@ -283,7 +301,7 @@ ...@@ -283,7 +301,7 @@
2007-01-04 Tom Tromey <tromey@redhat.com> 2007-01-04 Tom Tromey <tromey@redhat.com>
PR preprocessor/28165: PR preprocessor/28165
* internal.h (cpp_in_primary_file): New function. * internal.h (cpp_in_primary_file): New function.
* directives.c (do_include_next): Use cpp_in_primary_file. * directives.c (do_include_next): Use cpp_in_primary_file.
(do_pragma_once): Likewise. (do_pragma_once): Likewise.
...@@ -302,7 +320,7 @@ ...@@ -302,7 +320,7 @@
2006-12-28 Tom Tromey <tromey@redhat.com> 2006-12-28 Tom Tromey <tromey@redhat.com>
PR preprocessor/30001: PR preprocessor/30001
* charset.c (_cpp_convert_input): Check that to.len is greater * charset.c (_cpp_convert_input): Check that to.len is greater
than zero. than zero.
......
...@@ -475,7 +475,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) ...@@ -475,7 +475,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
_cpp_backup_tokens (pfile, 1); _cpp_backup_tokens (pfile, 1);
end_directive (pfile, skip); end_directive (pfile, skip);
if (was_parsing_args) if (was_parsing_args && !pfile->state.in_deferred_pragma)
{ {
/* Restore state when within macro args. */ /* Restore state when within macro args. */
pfile->state.parsing_args = 2; pfile->state.parsing_args = 2;
......
...@@ -41,11 +41,13 @@ struct macro_arg ...@@ -41,11 +41,13 @@ struct macro_arg
/* Macro expansion. */ /* Macro expansion. */
static int enter_macro_context (cpp_reader *, cpp_hashnode *); static int enter_macro_context (cpp_reader *, cpp_hashnode *,
const cpp_token *);
static int builtin_macro (cpp_reader *, cpp_hashnode *); static int builtin_macro (cpp_reader *, cpp_hashnode *);
static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
const cpp_token **, unsigned int); const cpp_token **, unsigned int);
static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *); static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *,
_cpp_buff **);
static cpp_context *next_context (cpp_reader *); static cpp_context *next_context (cpp_reader *);
static const cpp_token *padding_token (cpp_reader *, const cpp_token *); static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
static void expand_arg (cpp_reader *, macro_arg *); static void expand_arg (cpp_reader *, macro_arg *);
...@@ -55,7 +57,8 @@ static void paste_all_tokens (cpp_reader *, const cpp_token *); ...@@ -55,7 +57,8 @@ static void paste_all_tokens (cpp_reader *, const cpp_token *);
static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *); static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *);
static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *, static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
macro_arg *); macro_arg *);
static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *); static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *,
_cpp_buff **);
static bool create_iso_definition (cpp_reader *, cpp_macro *); static bool create_iso_definition (cpp_reader *, cpp_macro *);
/* #define directive parsing and handling. */ /* #define directive parsing and handling. */
...@@ -575,9 +578,12 @@ _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node ...@@ -575,9 +578,12 @@ _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node
invocation. Assumes the opening parenthesis has been processed. invocation. Assumes the opening parenthesis has been processed.
If there is an error, emits an appropriate diagnostic and returns If there is an error, emits an appropriate diagnostic and returns
NULL. Each argument is terminated by a CPP_EOF token, for the NULL. Each argument is terminated by a CPP_EOF token, for the
future benefit of expand_arg(). */ future benefit of expand_arg(). If there are any deferred
#pragma directives among macro arguments, store pointers to the
CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer. */
static _cpp_buff * static _cpp_buff *
collect_args (cpp_reader *pfile, const cpp_hashnode *node) collect_args (cpp_reader *pfile, const cpp_hashnode *node,
_cpp_buff **pragma_buff)
{ {
_cpp_buff *buff, *base_buff; _cpp_buff *buff, *base_buff;
cpp_macro *macro; cpp_macro *macro;
...@@ -645,6 +651,51 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node) ...@@ -645,6 +651,51 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node)
else if (token->type == CPP_EOF else if (token->type == CPP_EOF
|| (token->type == CPP_HASH && token->flags & BOL)) || (token->type == CPP_HASH && token->flags & BOL))
break; break;
else if (token->type == CPP_PRAGMA)
{
cpp_token *newtok = _cpp_temp_token (pfile);
/* CPP_PRAGMA token lives in directive_result, which will
be overwritten on the next directive. */
*newtok = *token;
token = newtok;
do
{
if (*pragma_buff == NULL
|| BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *))
{
_cpp_buff *next;
if (*pragma_buff == NULL)
*pragma_buff
= _cpp_get_buff (pfile, 32 * sizeof (cpp_token *));
else
{
next = *pragma_buff;
*pragma_buff
= _cpp_get_buff (pfile,
(BUFF_FRONT (*pragma_buff)
- (*pragma_buff)->base) * 2);
(*pragma_buff)->next = next;
}
}
*(const cpp_token **) BUFF_FRONT (*pragma_buff) = token;
BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *);
if (token->type == CPP_PRAGMA_EOL)
break;
token = cpp_get_token (pfile);
}
while (token->type != CPP_EOF);
/* In deferred pragmas parsing_args and prevent_expansion
had been changed, reset it. */
pfile->state.parsing_args = 2;
pfile->state.prevent_expansion = 1;
if (token->type == CPP_EOF)
break;
else
continue;
}
arg->first[ntokens++] = token; arg->first[ntokens++] = token;
} }
...@@ -709,9 +760,11 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node) ...@@ -709,9 +760,11 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node)
/* Search for an opening parenthesis to the macro of NODE, in such a /* Search for an opening parenthesis to the macro of NODE, in such a
way that, if none is found, we don't lose the information in any way that, if none is found, we don't lose the information in any
intervening padding tokens. If we find the parenthesis, collect intervening padding tokens. If we find the parenthesis, collect
the arguments and return the buffer containing them. */ the arguments and return the buffer containing them. PRAGMA_BUFF
argument is the same as in collect_args. */
static _cpp_buff * static _cpp_buff *
funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
_cpp_buff **pragma_buff)
{ {
const cpp_token *token, *padding = NULL; const cpp_token *token, *padding = NULL;
...@@ -728,7 +781,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) ...@@ -728,7 +781,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
if (token->type == CPP_OPEN_PAREN) if (token->type == CPP_OPEN_PAREN)
{ {
pfile->state.parsing_args = 2; pfile->state.parsing_args = 2;
return collect_args (pfile, node); return collect_args (pfile, node, pragma_buff);
} }
/* CPP_EOF can be the end of macro arguments, or the end of the /* CPP_EOF can be the end of macro arguments, or the end of the
...@@ -749,9 +802,13 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node) ...@@ -749,9 +802,13 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
/* Push the context of a macro with hash entry NODE onto the context /* Push the context of a macro with hash entry NODE onto the context
stack. If we can successfully expand the macro, we push a context stack. If we can successfully expand the macro, we push a context
containing its yet-to-be-rescanned replacement list and return one. containing its yet-to-be-rescanned replacement list and return one.
Otherwise, we don't push a context and return zero. */ If there were additionally any unexpanded deferred #pragma directives
among macro arguments, push another context containing the
pragma tokens before the yet-to-be-rescanned replacement list
and return two. Otherwise, we don't push a context and return zero. */
static int static int
enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
const cpp_token *result)
{ {
/* The presence of a macro invalidates a file's controlling macro. */ /* The presence of a macro invalidates a file's controlling macro. */
pfile->mi_valid = false; pfile->mi_valid = false;
...@@ -762,6 +819,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) ...@@ -762,6 +819,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
if (! (node->flags & NODE_BUILTIN)) if (! (node->flags & NODE_BUILTIN))
{ {
cpp_macro *macro = node->value.macro; cpp_macro *macro = node->value.macro;
_cpp_buff *pragma_buff = NULL;
if (macro->fun_like) if (macro->fun_like)
{ {
...@@ -770,7 +828,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) ...@@ -770,7 +828,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
pfile->state.prevent_expansion++; pfile->state.prevent_expansion++;
pfile->keep_tokens++; pfile->keep_tokens++;
pfile->state.parsing_args = 1; pfile->state.parsing_args = 1;
buff = funlike_invocation_p (pfile, node); buff = funlike_invocation_p (pfile, node, &pragma_buff);
pfile->state.parsing_args = 0; pfile->state.parsing_args = 0;
pfile->keep_tokens--; pfile->keep_tokens--;
pfile->state.prevent_expansion--; pfile->state.prevent_expansion--;
...@@ -782,6 +840,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) ...@@ -782,6 +840,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
"function-like macro \"%s\" must be used with arguments in traditional C", "function-like macro \"%s\" must be used with arguments in traditional C",
NODE_NAME (node)); NODE_NAME (node));
if (pragma_buff)
_cpp_release_buff (pfile, pragma_buff);
return 0; return 0;
} }
...@@ -798,6 +859,25 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node) ...@@ -798,6 +859,25 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
if (macro->paramc == 0) if (macro->paramc == 0)
_cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count); _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count);
if (pragma_buff)
{
if (!pfile->state.in_directive)
_cpp_push_token_context (pfile, NULL,
padding_token (pfile, result), 1);
do
{
_cpp_buff *tail = pragma_buff->next;
pragma_buff->next = NULL;
push_ptoken_context (pfile, NULL, pragma_buff,
(const cpp_token **) pragma_buff->base,
((const cpp_token **) BUFF_FRONT (pragma_buff)
- (const cpp_token **) pragma_buff->base));
pragma_buff = tail;
}
while (pragma_buff != NULL);
return 2;
}
return 1; return 1;
} }
...@@ -1144,14 +1224,17 @@ cpp_get_token (cpp_reader *pfile) ...@@ -1144,14 +1224,17 @@ cpp_get_token (cpp_reader *pfile)
if (!(node->flags & NODE_DISABLED)) if (!(node->flags & NODE_DISABLED))
{ {
int ret;
/* If not in a macro context, and we're going to start an /* If not in a macro context, and we're going to start an
expansion, record the location. */ expansion, record the location. */
if (can_set && !context->macro) if (can_set && !context->macro)
pfile->invocation_location = result->src_loc; pfile->invocation_location = result->src_loc;
if (!pfile->state.prevent_expansion if (pfile->state.prevent_expansion)
&& enter_macro_context (pfile, node)) break;
ret = enter_macro_context (pfile, node, result);
if (ret)
{ {
if (pfile->state.in_directive) if (pfile->state.in_directive || ret == 2)
continue; continue;
return padding_token (pfile, result); return padding_token (pfile, result);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment