preprocessor: Fix non-fn fn-like macro at EOF [PR97471]
authorNathan Sidwell <nathan@acm.org>
Mon, 19 Oct 2020 14:57:50 +0000 (07:57 -0700)
committerNathan Sidwell <nathan@acm.org>
Mon, 19 Oct 2020 15:00:41 +0000 (08:00 -0700)
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 [new file with mode: 0644]
libcpp/init.c
libcpp/internal.h
libcpp/macro.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 (file)
index 0000000..f1e512e
--- /dev/null
@@ -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
index 84c0a9efa74b7d62b3a0a776bab3a3b473b54ed2..454a183134af9d4eea8be5a0d02915419141af08 100644 (file)
@@ -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);
index b728df7456265f98ee6e11a3142178de6efa2a73..b1a2a996ef60e6e01e13af5fcdaf41afb17b8552 100644 (file)
@@ -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;
index 2c7d7322e09c6ca425b58392f591dc5bc87de70f..9cb3b10a9a0f3e785ca6d964e0c9aa56ac02041c 100644 (file)
@@ -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;
 }