From 5abe05b4331250b6a7798ce87c0a82adc2bd70f3 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 19 Oct 2020 07:57:50 -0700 Subject: [PATCH] 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. --- gcc/testsuite/c-c++-common/cpp/pr97471.c | 10 ++++++++++ libcpp/init.c | 6 ++++-- libcpp/internal.h | 4 ++-- libcpp/macro.c | 20 ++++++++------------ 4 files changed, 24 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/cpp/pr97471.c diff --git a/gcc/testsuite/c-c++-common/cpp/pr97471.c b/gcc/testsuite/c-c++-common/cpp/pr97471.c new file mode 100644 index 00000000000..f1e512ea331 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/pr97471.c @@ -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 diff --git a/libcpp/init.c b/libcpp/init.c index 84c0a9efa74..454a183134a 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -248,8 +248,10 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, /* Set up static tokens. */ pfile->avoid_paste.type = CPP_PADDING; pfile->avoid_paste.val.source = NULL; - pfile->eof.type = CPP_EOF; - pfile->eof.flags = 0; + pfile->avoid_paste.src_loc = 0; + pfile->endarg.type = CPP_EOF; + pfile->endarg.flags = 0; + pfile->endarg.src_loc = 0; /* Create a token buffer for the lexer. */ _cpp_init_tokenrun (&pfile->base_run, 250); diff --git a/libcpp/internal.h b/libcpp/internal.h index b728df74562..b1a2a996ef6 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -517,9 +517,9 @@ struct cpp_reader set to -1 to disable it or to a non-negative value to enable it. */ 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 eof; + cpp_token endarg; /* Opaque handle to the dependencies of mkdeps.c. */ class mkdeps *deps; diff --git a/libcpp/macro.c b/libcpp/macro.c index 2c7d7322e09..9cb3b10a9a0 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1241,7 +1241,8 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node, 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, 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); } - /* 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 - up more than one token when expanding macros is in general - too difficult. We re-insert it in its own context. */ - _cpp_backup_tokens (pfile, 1); - if (padding) - _cpp_push_token_context (pfile, NULL, padding, 1); - } + /* Back up. We may have skipped padding, in which case backing + up more than one token when expanding macros is in general + too difficult. We re-insert it in its own context. */ + _cpp_backup_tokens (pfile, 1); + if (padding) + _cpp_push_token_context (pfile, NULL, padding, 1); return NULL; } -- 2.30.2