summaryrefslogtreecommitdiff
path: root/gas/input-scrub.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/input-scrub.c')
-rw-r--r--gas/input-scrub.c88
1 files changed, 55 insertions, 33 deletions
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index 37877bffe1c..f65cd7957b1 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -80,7 +80,7 @@ static size_t sb_index = -1;
static sb from_sb;
/* Should we do a conditional check on from_sb? */
-static int from_sb_is_expansion = 1;
+static enum expansion from_sb_expansion = expanding_none;
/* The number of nested sb structures we have included. */
int macro_nest;
@@ -102,7 +102,7 @@ static const char *logical_input_file;
/* 1-origin line number in a source file. */
/* A line ends in '\n' or eof. */
static unsigned int physical_input_line;
-static int logical_input_line;
+static unsigned int logical_input_line;
/* Struct used to save the state of the input handler during include files */
struct input_save {
@@ -111,13 +111,13 @@ struct input_save {
size_t partial_size;
char save_source[AFTER_SIZE];
size_t buffer_length;
- const char * physical_input_file;
- const char * logical_input_file;
+ const char * physical_input_file;
+ const char * logical_input_file;
unsigned int physical_input_line;
- int logical_input_line;
+ unsigned int logical_input_line;
size_t sb_index;
sb from_sb;
- int from_sb_is_expansion; /* Should we do a conditional check? */
+ enum expansion from_sb_expansion; /* Should we do a conditional check? */
struct input_save * next_saved_file; /* Chain of input_saves. */
char * input_file_save; /* Saved state of input routines. */
char * saved_position; /* Caller's saved position in buf. */
@@ -137,7 +137,7 @@ static void
input_scrub_reinit (void)
{
input_file_begin (); /* Reinitialize! */
- logical_input_line = -1;
+ logical_input_line = -1u;
logical_input_file = NULL;
buffer_length = input_file_buffer_size () * 2;
@@ -167,7 +167,7 @@ input_scrub_push (char *saved_position)
saved->logical_input_line = logical_input_line;
saved->sb_index = sb_index;
saved->from_sb = from_sb;
- saved->from_sb_is_expansion = from_sb_is_expansion;
+ saved->from_sb_expansion = from_sb_expansion;
memcpy (saved->save_source, save_source, sizeof (save_source));
saved->next_saved_file = next_saved_file;
saved->input_file_save = input_file_push ();
@@ -196,7 +196,7 @@ input_scrub_pop (struct input_save *saved)
logical_input_line = saved->logical_input_line;
sb_index = saved->sb_index;
from_sb = saved->from_sb;
- from_sb_is_expansion = saved->from_sb_is_expansion;
+ from_sb_expansion = saved->from_sb_expansion;
partial_where = saved->partial_where;
partial_size = saved->partial_size;
next_saved_file = saved->next_saved_file;
@@ -252,6 +252,7 @@ char *
input_scrub_include_file (const char *filename, char *position)
{
next_saved_file = input_scrub_push (position);
+ from_sb_expansion = expanding_none;
return input_scrub_new_file (filename);
}
@@ -259,7 +260,7 @@ input_scrub_include_file (const char *filename, char *position)
expanding a macro. */
void
-input_scrub_include_sb (sb *from, char *position, int is_expansion)
+input_scrub_include_sb (sb *from, char *position, enum expansion expansion)
{
int newline;
@@ -267,8 +268,10 @@ input_scrub_include_sb (sb *from, char *position, int is_expansion)
as_fatal (_("macros nested too deeply"));
++macro_nest;
+ gas_assert (expansion < expanding_nested);
+
#ifdef md_macro_start
- if (is_expansion)
+ if (expansion == expanding_macro)
{
md_macro_start ();
}
@@ -279,7 +282,9 @@ input_scrub_include_sb (sb *from, char *position, int is_expansion)
/* Allocate sufficient space: from->len + optional newline. */
newline = from->len >= 1 && from->ptr[0] != '\n';
sb_build (&from_sb, from->len + newline);
- from_sb_is_expansion = is_expansion;
+ if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro)
+ expansion = expanding_nested;
+ from_sb_expansion = expansion;
if (newline)
{
/* Add the sentinel required by read.c. */
@@ -304,7 +309,7 @@ input_scrub_close (void)
{
input_file_close ();
physical_input_line = 0;
- logical_input_line = -1;
+ logical_input_line = -1u;
}
char *
@@ -317,7 +322,7 @@ input_scrub_next_buffer (char **bufp)
if (sb_index >= from_sb.len)
{
sb_kill (&from_sb);
- if (from_sb_is_expansion)
+ if (from_sb_expansion == expanding_macro)
{
cond_finish_check (macro_nest);
#ifdef md_macro_end
@@ -429,22 +434,23 @@ void
bump_line_counters (void)
{
if (sb_index == (size_t) -1)
- {
- ++physical_input_line;
- if (logical_input_line >= 0)
- ++logical_input_line;
- }
+ ++physical_input_line;
+
+ /* PR gas/16908 workaround: Don't bump logical line numbers while
+ expanding macros, unless file (and maybe line; see as_where()) are
+ used inside the macro. */
+ if (logical_input_line != -1u && from_sb_expansion < expanding_macro)
+ ++logical_input_line;
}
/* Tells us what the new logical line number and file are.
If the line_number is -1, we don't change the current logical line
- number. If it is -2, we decrement the logical line number (this is
- to support the .appfile pseudo-op inserted into the stream by
- do_scrub_chars).
- If the fname is NULL, we don't change the current logical file name.
+ number.
+ If fname is NULL, we don't change the current logical file name, unless
+ bit 3 of flags is set.
Returns nonzero if the filename actually changes. */
-int
+void
new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it! */
int line_number,
int flags)
@@ -461,6 +467,18 @@ new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it!
case 1 << 2:
/* FIXME: we could check that include nesting is correct. */
break;
+ case 1 << 3:
+ if (line_number < 0 || fname != NULL || next_saved_file == NULL)
+ abort ();
+ /* PR gas/16908 workaround: Ignore updates when nested inside a macro
+ expansion. */
+ if (from_sb_expansion == expanding_nested)
+ return;
+ if (next_saved_file->logical_input_file)
+ fname = next_saved_file->logical_input_file;
+ else
+ fname = next_saved_file->physical_input_file;
+ break;
default:
abort ();
}
@@ -477,18 +495,22 @@ new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it!
if (fname
&& (logical_input_file == NULL
|| filename_cmp (logical_input_file, fname)))
- {
- logical_input_file = fname;
- return 1;
- }
- else
- return 0;
+ logical_input_file = fname;
+
+ /* When encountering file or line changes inside a macro, arrange for
+ bump_line_counters() to henceforth increment the logical line number
+ again, just like it does when expanding repeats. See as_where() for
+ why changing file or line alone doesn't alter expansion mode. */
+ if (from_sb_expansion == expanding_macro
+ && logical_input_file != NULL
+ && logical_input_line != -1u)
+ from_sb_expansion = expanding_repeat;
}
-int
+void
new_logical_line (const char *fname, int line_number)
{
- return new_logical_line_flags (fname, line_number, 0);
+ new_logical_line_flags (fname, line_number, 0);
}
@@ -515,7 +537,7 @@ const char *
as_where (unsigned int *linep)
{
if (logical_input_file != NULL
- && (linep == NULL || logical_input_line >= 0))
+ && (linep == NULL || logical_input_line != -1u))
{
if (linep != NULL)
*linep = logical_input_line;