mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-26 02:24:01 +08:00
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
This commit is contained in:
parent
1525f2c3a5
commit
765d600ac5
@ -1,3 +1,9 @@
|
||||
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>
|
||||
|
||||
* gcc.dg/struct/wo_prof_malloc_size_var.c: UnXFAIL.
|
||||
|
35
gcc/testsuite/gcc.dg/cpp/pr34692.c
Normal file
35
gcc/testsuite/gcc.dg/cpp/pr34692.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* 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
|
26
gcc/testsuite/gcc.dg/gomp/pr34692.c
Normal file
26
gcc/testsuite/gcc.dg/gomp/pr34692.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* 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);
|
||||
}
|
||||
}
|
@ -1,12 +1,30 @@
|
||||
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>
|
||||
|
||||
PR c++/34859:
|
||||
PR c++/34859
|
||||
* macro.c (_cpp_create_definition): Handle __STDC_LIMIT_MACROS and
|
||||
__STDC_CONSTANT_MACROS.
|
||||
|
||||
2008-01-07 Fred Fish <fnf@specifix.com>
|
||||
|
||||
PR preprocessor/30363:
|
||||
PR preprocessor/30363
|
||||
* traditional.c (replace_args_and_push): Add local variable
|
||||
cxtquote, calculate the replacement text size assuming a
|
||||
worst case of every input character quoted with backslash,
|
||||
@ -15,7 +33,7 @@
|
||||
|
||||
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.
|
||||
(do_linemarker): Add comment.
|
||||
|
||||
@ -26,7 +44,7 @@
|
||||
|
||||
2007-12-06 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR c/29172:
|
||||
PR c/29172
|
||||
* internal.h (struct cpp_reader) <file_hash_entries>: Changed
|
||||
type.
|
||||
<file_hash_entries_allocated, file_hash_entries_used>: Removed.
|
||||
@ -43,13 +61,13 @@
|
||||
|
||||
2007-12-03 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/34288:
|
||||
PR preprocessor/34288
|
||||
* configure.ac, config.in: Rebuilt.
|
||||
* configure.ac: Check for ssize_t.
|
||||
|
||||
2007-11-30 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/32868:
|
||||
PR preprocessor/32868
|
||||
* macro.c (_cpp_create_definition): Special case
|
||||
__STDC_FORMAT_MACROS.
|
||||
|
||||
@ -59,7 +77,7 @@
|
||||
|
||||
2007-11-11 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR c++/17557:
|
||||
PR c++/17557
|
||||
* include/cpplib.h (cpp_included_before): Declare.
|
||||
* files.c (struct file_hash_entry) <location>: New field.
|
||||
(_cpp_find_file): Initialize new field.
|
||||
@ -68,13 +86,13 @@
|
||||
|
||||
2007-11-01 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/30805:
|
||||
PR preprocessor/30805
|
||||
* macro.c (paste_tokens): Handle padding token.
|
||||
(paste_tokens): Don't abort unless padding has PASTE_LEFT flag.
|
||||
|
||||
2007-10-31 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/30786:
|
||||
PR preprocessor/30786
|
||||
* macro.c (builtin_macro): Return result of _cpp_do__Pragma.
|
||||
* directives.c (_cpp_do__Pragma): Return error status.
|
||||
* internal.h (_cpp_do__Pragma): Update.
|
||||
@ -112,7 +130,7 @@
|
||||
|
||||
2007-08-18 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/32974:
|
||||
PR preprocessor/32974
|
||||
* directives.c (parse_include): Don't check for EOL when
|
||||
processing #pragma dependency.
|
||||
|
||||
@ -227,7 +245,7 @@
|
||||
|
||||
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.
|
||||
|
||||
2007-03-30 Michael Meissner <michael.meissner@amd.com>
|
||||
@ -247,13 +265,13 @@
|
||||
|
||||
2007-01-30 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/30468:
|
||||
PR preprocessor/30468
|
||||
* mkdeps.c (apply_vpath): Strip successive '/'s if we stripped
|
||||
'./'.
|
||||
|
||||
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
|
||||
cur_token.
|
||||
(_cpp_create_definition): Don't restore cur_token here.
|
||||
@ -265,7 +283,7 @@
|
||||
|
||||
2007-01-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/28227:
|
||||
PR preprocessor/28227
|
||||
* directives.c (lex_macro_node): Added 'is_def_or_undef'
|
||||
argument.
|
||||
(do_define): Update.
|
||||
@ -283,7 +301,7 @@
|
||||
|
||||
2007-01-04 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR preprocessor/28165:
|
||||
PR preprocessor/28165
|
||||
* internal.h (cpp_in_primary_file): New function.
|
||||
* directives.c (do_include_next): Use cpp_in_primary_file.
|
||||
(do_pragma_once): Likewise.
|
||||
@ -302,7 +320,7 @@
|
||||
|
||||
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
|
||||
than zero.
|
||||
|
||||
|
@ -475,7 +475,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
|
||||
end_directive (pfile, skip);
|
||||
if (was_parsing_args)
|
||||
if (was_parsing_args && !pfile->state.in_deferred_pragma)
|
||||
{
|
||||
/* Restore state when within macro args. */
|
||||
pfile->state.parsing_args = 2;
|
||||
|
111
libcpp/macro.c
111
libcpp/macro.c
@ -41,11 +41,13 @@ struct macro_arg
|
||||
|
||||
/* 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 void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
|
||||
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 const cpp_token *padding_token (cpp_reader *, const cpp_token *);
|
||||
static void expand_arg (cpp_reader *, macro_arg *);
|
||||
@ -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 void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
|
||||
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 *);
|
||||
|
||||
/* #define directive parsing and handling. */
|
||||
@ -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.
|
||||
If there is an error, emits an appropriate diagnostic and returns
|
||||
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 *
|
||||
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_macro *macro;
|
||||
@ -645,6 +651,51 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node)
|
||||
else if (token->type == CPP_EOF
|
||||
|| (token->type == CPP_HASH && token->flags & BOL))
|
||||
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;
|
||||
}
|
||||
@ -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
|
||||
way that, if none is found, we don't lose the information in any
|
||||
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 *
|
||||
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;
|
||||
|
||||
@ -728,7 +781,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
|
||||
if (token->type == CPP_OPEN_PAREN)
|
||||
{
|
||||
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
|
||||
@ -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
|
||||
stack. If we can successfully expand the macro, we push a context
|
||||
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
|
||||
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. */
|
||||
pfile->mi_valid = false;
|
||||
@ -762,6 +819,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
|
||||
if (! (node->flags & NODE_BUILTIN))
|
||||
{
|
||||
cpp_macro *macro = node->value.macro;
|
||||
_cpp_buff *pragma_buff = NULL;
|
||||
|
||||
if (macro->fun_like)
|
||||
{
|
||||
@ -770,7 +828,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
|
||||
pfile->state.prevent_expansion++;
|
||||
pfile->keep_tokens++;
|
||||
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->keep_tokens--;
|
||||
pfile->state.prevent_expansion--;
|
||||
@ -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",
|
||||
NODE_NAME (node));
|
||||
|
||||
if (pragma_buff)
|
||||
_cpp_release_buff (pfile, pragma_buff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -798,6 +859,25 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
|
||||
if (macro->paramc == 0)
|
||||
_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;
|
||||
}
|
||||
|
||||
@ -1144,14 +1224,17 @@ cpp_get_token (cpp_reader *pfile)
|
||||
|
||||
if (!(node->flags & NODE_DISABLED))
|
||||
{
|
||||
int ret;
|
||||
/* If not in a macro context, and we're going to start an
|
||||
expansion, record the location. */
|
||||
if (can_set && !context->macro)
|
||||
pfile->invocation_location = result->src_loc;
|
||||
if (!pfile->state.prevent_expansion
|
||||
&& enter_macro_context (pfile, node))
|
||||
if (pfile->state.prevent_expansion)
|
||||
break;
|
||||
ret = enter_macro_context (pfile, node, result);
|
||||
if (ret)
|
||||
{
|
||||
if (pfile->state.in_directive)
|
||||
if (pfile->state.in_directive || ret == 2)
|
||||
continue;
|
||||
return padding_token (pfile, result);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user