aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2020-10-28 18:41:24 +0100
committerThomas Koenig <tkoenig@gcc.gnu.org>2020-10-28 18:41:24 +0100
commitbf6dad60c338a42a7fb85f7b2a5870c0fb2e20f8 (patch)
treee513781ef717465e7db0358e987a5a6cbef5665c /libcpp
parent0c261d5b5c931d9e9214d06531bdc7e9e16aeaab (diff)
parent47d13acbda9a5d8eb57ff169ba74857cd54108e4 (diff)
downloadgcc-bf6dad60c338a42a7fb85f7b2a5870c0fb2e20f8.zip
gcc-bf6dad60c338a42a7fb85f7b2a5870c0fb2e20f8.tar.gz
gcc-bf6dad60c338a42a7fb85f7b2a5870c0fb2e20f8.tar.bz2
Merge branch 'master' into devel/coarray_native.
Merge into devel/coarray_native to prepare for later merging of coarray_native with master.
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog33
-rw-r--r--libcpp/files.c10
-rw-r--r--libcpp/init.c148
-rw-r--r--libcpp/internal.h8
-rw-r--r--libcpp/lex.c9
-rw-r--r--libcpp/macro.c32
6 files changed, 149 insertions, 91 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 7fb267e..61bfe81 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,36 @@
+2020-10-20 Nathan Sidwell <nathan@acm.org>
+
+ * lex.c (_cpp_lex_direct): Do not complete EOF processing when
+ parsing_args.
+ * macro.c (collect_args): Do not unwind fake EOF.
+ (funlike_invocation_p): Do not unwind fake EOF.
+ (cpp_context): Replace abort with gcc_assert.
+
+2020-10-19 Nathan Sidwell <nathan@acm.org>
+
+ * 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.
+
+2020-10-08 Nathan Sidwell <nathan@acm.org>
+
+ * internal.h (enum include_type): Rename IT_MAIN_INJECT to
+ IT_PRE_MAIN.
+ * init.c (cpp_read_main_file): If there is no line marker, adjust
+ the initial line marker.
+ (read_original_filename): Return bool, peek the buffer directly
+ before trying to tokenize.
+ (read_original_directory): Likewise. Directly prod the string
+ literal.
+ * files.c (_cpp_stack_file): Adjust for IT_PRE_MAIN change.
+
+2020-09-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/97163
+ * lex.c (search_line_fast): Only use _ARCH_PWR8 Altivec version
+ for GCC >= 4.5.
+
2020-09-17 Patrick Palka <ppalka@redhat.com>
PR c/80076
diff --git a/libcpp/files.c b/libcpp/files.c
index b890b8e..5af4136 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -948,10 +948,12 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
/* Add line map and do callbacks. */
_cpp_do_file_change (pfile, LC_ENTER, file->path,
- /* With preamble injection, start on line zero, so
- the preamble doesn't appear to have been
- included from line 1. */
- type == IT_MAIN_INJECT ? 0 : 1, sysp);
+ /* With preamble injection, start on line zero,
+ so the preamble doesn't appear to have been
+ included from line 1. Likewise when
+ starting preprocessed, we expect an initial
+ locating line. */
+ type == IT_PRE_MAIN ? 0 : 1, sysp);
return true;
}
diff --git a/libcpp/init.c b/libcpp/init.c
index aba5854..454a183 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -36,7 +36,7 @@ along with this program; see the file COPYING3. If not see
static void init_library (void);
static void mark_named_operators (cpp_reader *, int);
-static void read_original_filename (cpp_reader *);
+static bool read_original_filename (cpp_reader *);
static void read_original_directory (cpp_reader *);
static void post_options (cpp_reader *);
@@ -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);
@@ -681,94 +683,114 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname, bool injecting)
return NULL;
_cpp_stack_file (pfile, pfile->main_file,
- injecting ? IT_MAIN_INJECT : IT_MAIN, 0);
+ injecting || CPP_OPTION (pfile, preprocessed)
+ ? IT_PRE_MAIN : IT_MAIN, 0);
/* For foo.i, read the original filename foo.c now, for the benefit
of the front ends. */
if (CPP_OPTION (pfile, preprocessed))
- read_original_filename (pfile);
+ if (!read_original_filename (pfile))
+ {
+ /* We're on line 1 after all. */
+ auto *last = linemap_check_ordinary
+ (LINEMAPS_LAST_MAP (pfile->line_table, false));
+ last->to_line = 1;
+ /* Inform of as-if a file change. */
+ _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, LINEMAP_FILE (last),
+ LINEMAP_LINE (last), LINEMAP_SYSP (last));
+ }
return ORDINARY_MAP_FILE_NAME (LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table));
}
-/* For preprocessed files, if the first tokens are of the form # NUM.
- handle the directive so we know the original file name. This will
- generate file_change callbacks, which the front ends must handle
- appropriately given their state of initialization. */
-static void
+/* For preprocessed files, if the very first characters are
+ '#<SPACE>[01]<SPACE>', then handle a line directive so we know the
+ original file name. This will generate file_change callbacks,
+ which the front ends must handle appropriately given their state of
+ initialization. We peek directly into the character buffer, so
+ that we're not confused by otherwise-skipped white space &
+ comments. We can be very picky, because this should have been
+ machine-generated text (by us, no less). This way we do not
+ interfere with the module directive state machine. */
+
+static bool
read_original_filename (cpp_reader *pfile)
{
- const cpp_token *token, *token1;
-
- /* Lex ahead; if the first tokens are of the form # NUM, then
- process the directive, otherwise back up. */
- token = _cpp_lex_direct (pfile);
- if (token->type == CPP_HASH)
+ auto *buf = pfile->buffer->next_line;
+
+ if (pfile->buffer->rlimit - buf > 4
+ && buf[0] == '#'
+ && buf[1] == ' '
+ // Also permit '1', as that's what used to be here
+ && (buf[2] == '0' || buf[2] == '1')
+ && buf[3] == ' ')
{
- pfile->state.in_directive = 1;
- token1 = _cpp_lex_direct (pfile);
- _cpp_backup_tokens (pfile, 1);
- pfile->state.in_directive = 0;
-
- /* If it's a #line directive, handle it. */
- if (token1->type == CPP_NUMBER
- && _cpp_handle_directive (pfile, token->flags & PREV_WHITE))
+ const cpp_token *token = _cpp_lex_direct (pfile);
+ gcc_checking_assert (token->type == CPP_HASH);
+ if (_cpp_handle_directive (pfile, token->flags & PREV_WHITE))
{
read_original_directory (pfile);
- return;
+ return true;
}
}
- /* Backup as if nothing happened. */
- _cpp_backup_tokens (pfile, 1);
+ return false;
}
/* For preprocessed files, if the tokens following the first filename
line is of the form # <line> "/path/name//", handle the
- directive so we know the original current directory. */
+ directive so we know the original current directory.
+
+ As with the first line peeking, we can do this without lexing by
+ being picky. */
static void
read_original_directory (cpp_reader *pfile)
{
- const cpp_token *hash, *token;
-
- /* Lex ahead; if the first tokens are of the form # NUM, then
- process the directive, otherwise back up. */
- hash = _cpp_lex_direct (pfile);
- if (hash->type != CPP_HASH)
+ auto *buf = pfile->buffer->next_line;
+
+ if (pfile->buffer->rlimit - buf > 4
+ && buf[0] == '#'
+ && buf[1] == ' '
+ // Also permit '1', as that's what used to be here
+ && (buf[2] == '0' || buf[2] == '1')
+ && buf[3] == ' ')
{
- _cpp_backup_tokens (pfile, 1);
- return;
- }
-
- token = _cpp_lex_direct (pfile);
+ const cpp_token *hash = _cpp_lex_direct (pfile);
+ gcc_checking_assert (hash->type == CPP_HASH);
+ pfile->state.in_directive = 1;
+ const cpp_token *number = _cpp_lex_direct (pfile);
+ gcc_checking_assert (number->type == CPP_NUMBER);
+ const cpp_token *string = _cpp_lex_direct (pfile);
+ pfile->state.in_directive = 0;
- if (token->type != CPP_NUMBER)
- {
- _cpp_backup_tokens (pfile, 2);
- return;
- }
+ const unsigned char *text = nullptr;
+ size_t len = 0;
+ if (string->type == CPP_STRING)
+ {
+ /* The string value includes the quotes. */
+ text = string->val.str.text;
+ len = string->val.str.len;
+ }
+ if (len < 5
+ || !IS_DIR_SEPARATOR (text[len - 2])
+ || !IS_DIR_SEPARATOR (text[len - 3]))
+ {
+ /* That didn't work out, back out. */
+ _cpp_backup_tokens (pfile, 3);
+ return;
+ }
- token = _cpp_lex_direct (pfile);
+ if (pfile->cb.dir_change)
+ {
+ /* Smash the string directly, it's dead at this point */
+ char *smashy = (char *)text;
+ smashy[len - 3] = 0;
+
+ pfile->cb.dir_change (pfile, smashy + 1);
+ }
- if (token->type != CPP_STRING
- || ! (token->val.str.len >= 5
- && IS_DIR_SEPARATOR (token->val.str.text[token->val.str.len-2])
- && IS_DIR_SEPARATOR (token->val.str.text[token->val.str.len-3])))
- {
- _cpp_backup_tokens (pfile, 3);
- return;
+ /* We should be at EOL. */
}
-
- if (pfile->cb.dir_change)
- {
- char *debugdir = (char *) alloca (token->val.str.len - 3);
-
- memcpy (debugdir, (const char *) token->val.str.text + 1,
- token->val.str.len - 4);
- debugdir[token->val.str.len - 4] = '\0';
-
- pfile->cb.dir_change (pfile, debugdir);
- }
}
/* This is called at the end of preprocessing. It pops the last
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 4bafe1c..b1a2a99 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -124,8 +124,8 @@ enum include_type
IT_CMDLINE, /* -include */
IT_DEFAULT, /* forced header */
IT_MAIN, /* main, start on line 1 */
- IT_MAIN_INJECT, /* main, but there will be an injected preamble
- before line 1 */
+ IT_PRE_MAIN, /* main, but there will be a preamble before line
+ 1 */
IT_DIRECTIVE_HWM = IT_IMPORT + 1, /* Directives below this. */
IT_HEADER_HWM = IT_DEFAULT + 1 /* Header files below this. */
@@ -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/lex.c b/libcpp/lex.c
index 9aec9e0..fb22292 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -531,11 +531,11 @@ init_vectorized_lexer (void)
search_line_fast = impl;
}
-#elif defined(_ARCH_PWR8) && defined(__ALTIVEC__)
+#elif (GCC_VERSION >= 4005) && defined(_ARCH_PWR8) && defined(__ALTIVEC__)
/* A vection of the fast scanner using AltiVec vectorized byte compares
and VSX unaligned loads (when VSX is available). This is otherwise
- the same as the pre-GCC 5 version. */
+ the same as the AltiVec version. */
ATTRIBUTE_NO_SANITIZE_UNDEFINED
static const uchar *
@@ -2768,7 +2768,10 @@ _cpp_lex_direct (cpp_reader *pfile)
if (!_cpp_get_fresh_line (pfile))
{
result->type = CPP_EOF;
- if (!pfile->state.in_directive)
+ /* Not a real EOF in a directive or arg parsing -- we refuse
+ to advance to the next file now, and will once we're out
+ of those modes. */
+ if (!pfile->state.in_directive && !pfile->state.parsing_args)
{
/* Tell the compiler the line number of the EOF token. */
result->src_loc = pfile->line_table->highest_line;
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 2c7d732..0874028 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));
@@ -1258,13 +1259,10 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node,
if (token->type == CPP_EOF)
{
- /* We still need the CPP_EOF to end directives, to end
- pre-expansion of a macro argument, and at the end of the main
- file. We do not want it at the end of a -include'd (forced)
- header file. */
- if (pfile->state.in_directive
- || !pfile->line_table->depth
- || pfile->context->prev)
+ /* Unless the EOF is marking the end of an argument, it's a fake
+ one from the end of a file that _cpp_clean_line will not have
+ advanced past. */
+ if (token == &pfile->endarg)
_cpp_backup_tokens (pfile, 1);
cpp_error (pfile, CPP_DL_ERROR,
"unterminated argument list invoking macro \"%s\"",
@@ -1327,14 +1325,15 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
pfile->state.parsing_args = 2;
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. A CPP_EOF is either an EOF from an argument we're
+ expanding, or a fake one from lex_direct. We want to backup the
+ former, but not the latter. 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. */
+ if (token->type != CPP_EOF || token == &pfile->endarg)
{
- /* 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);
@@ -2642,8 +2641,7 @@ _cpp_pop_context (cpp_reader *pfile)
cpp_context *context = pfile->context;
/* We should not be popping the base context. */
- if (context == &pfile->base_context)
- abort ();
+ gcc_assert (context != &pfile->base_context);
if (context->c.macro)
{