preprocessor: Fix non-fn fn-like macro at EOF [PR97471]

We inject EOF tokens between macro argument lists, but had
confused/stale logic in the non-fn invocation.  Renamed the magic
'eof' token, as it's now only used for macro argument termination.
Always rewind the non-OPEN_PAREN token.

	libcpp/
	* internal.h (struct cpp_reader): Rename 'eof' field to 'endarg'.
	* init.c (cpp_create_reader): Adjust.
	* macro.c (collect_args): Use endarg for separator.  Always rewind
	in the not-fn case.
	gcc/testsuite/
	* c-c++-common/cpp/pr97471.c: New.
This commit is contained in:
Nathan Sidwell 2020-10-19 07:57:50 -07:00
parent 8d31eb8f17
commit 5abe05b433
4 changed files with 24 additions and 16 deletions

View File

@ -0,0 +1,10 @@
/* PR preprocessor/97471 */
/* { dg-do compile } */
/* ICE with non-fn use of fn-like macro at EOF */
#define a() b
/* { dg-error "expected" "" { target c } .+2 } */
/* { dg-error "does not name" "" { target c++ } .+1 } */
a

View File

@ -248,8 +248,10 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
/* Set up static tokens. */ /* Set up static tokens. */
pfile->avoid_paste.type = CPP_PADDING; pfile->avoid_paste.type = CPP_PADDING;
pfile->avoid_paste.val.source = NULL; pfile->avoid_paste.val.source = NULL;
pfile->eof.type = CPP_EOF; pfile->avoid_paste.src_loc = 0;
pfile->eof.flags = 0; pfile->endarg.type = CPP_EOF;
pfile->endarg.flags = 0;
pfile->endarg.src_loc = 0;
/* Create a token buffer for the lexer. */ /* Create a token buffer for the lexer. */
_cpp_init_tokenrun (&pfile->base_run, 250); _cpp_init_tokenrun (&pfile->base_run, 250);

View File

@ -517,9 +517,9 @@ struct cpp_reader
set to -1 to disable it or to a non-negative value to enable it. */ set to -1 to disable it or to a non-negative value to enable it. */
time_t source_date_epoch; time_t source_date_epoch;
/* EOF token, and a token forcing paste avoidance. */ /* A token forcing paste avoidance, and one demarking macro arguments. */
cpp_token avoid_paste; cpp_token avoid_paste;
cpp_token eof; cpp_token endarg;
/* Opaque handle to the dependencies of mkdeps.c. */ /* Opaque handle to the dependencies of mkdeps.c. */
class mkdeps *deps; class mkdeps *deps;

View File

@ -1241,7 +1241,8 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node,
ntokens--; ntokens--;
arg->count = ntokens; arg->count = ntokens;
set_arg_token (arg, &pfile->eof, pfile->eof.src_loc, /* Append an EOF to mark end-of-argument. */
set_arg_token (arg, &pfile->endarg, token->src_loc,
ntokens, MACRO_ARG_TOKEN_NORMAL, ntokens, MACRO_ARG_TOKEN_NORMAL,
CPP_OPTION (pfile, track_macro_expansion)); CPP_OPTION (pfile, track_macro_expansion));
@ -1328,17 +1329,12 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
return collect_args (pfile, node, pragma_buff, num_args); return collect_args (pfile, node, pragma_buff, num_args);
} }
/* CPP_EOF can be the end of macro arguments, or the end of the
file. We mustn't back up over the latter. Ugh. */
if (token->type != CPP_EOF || token == &pfile->eof)
{
/* Back up. We may have skipped padding, in which case backing /* Back up. We may have skipped padding, in which case backing
up more than one token when expanding macros is in general up more than one token when expanding macros is in general
too difficult. We re-insert it in its own context. */ too difficult. We re-insert it in its own context. */
_cpp_backup_tokens (pfile, 1); _cpp_backup_tokens (pfile, 1);
if (padding) if (padding)
_cpp_push_token_context (pfile, NULL, padding, 1); _cpp_push_token_context (pfile, NULL, padding, 1);
}
return NULL; return NULL;
} }