2005-04-25  Jan Beulich  <jbeulich@novell.com>

	* macro.c (macro_expand_body): Replace locals indicator parameters
	with actual macro_entry. New local variables macro_line and err.
	Don't return when encountering an error, just record the fact.
	Detect local symbol name colliding with parameter. Track line number
	inside of macro expansion.
	(do_formals): Move local variable name to wider scope. Check
	parameter of the same name doesn't already exist. In MRI mode, also
	check it doesn't collide with the argument count pseudo-parameter).
	(define_macro): Add file and line number parameters. Remove local
	variable namestr. New local variable error. Initialize macro_entry
	members file, line, and name. Don't return when encountering an
	error, just record the fact. Use %s in some diagnostics for read.c
	to insert the macro name. Free macro_entry on error.
	(macro_expand): Pass macro_entry to macro_epand_body. Don't return
	when encountering an error, just record the fact.
	(expand_irp): Don't return when encountering an error, just record
	the fact.
	* macro.h (macro_struct): New members name, file, and line.
	(define_macro): Add file and line number parameters.
	* read.c (s_macro): Pass file and line to define_macro. Tag warning
	regarding pseudo-op redefinition with the file/line that macro
	definition started at.

gas/testsuite/
2005-04-25  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/badarg.s: Add tests for collisions between/among macro
	parameters and local symbols.
	* gas/macros/badarg.l: Adjust.
This commit is contained in:
Jan Beulich 2005-04-25 06:43:46 +00:00
parent fc41e3d163
commit 02ddf15681
7 changed files with 153 additions and 59 deletions

View File

@ -1,3 +1,28 @@
2005-04-25 Jan Beulich <jbeulich@novell.com>
* macro.c (macro_expand_body): Replace locals indicator parameters
with actual macro_entry. New local variables macro_line and err.
Don't return when encountering an error, just record the fact.
Detect local symbol name colliding with parameter. Track line number
inside of macro expansion.
(do_formals): Move local variable name to wider scope. Check
parameter of the same name doesn't already exist. In MRI mode, also
check it doesn't collide with the argument count pseudo-parameter).
(define_macro): Add file and line number parameters. Remove local
variable namestr. New local variable error. Initialize macro_entry
members file, line, and name. Don't return when encountering an
error, just record the fact. Use %s in some diagnostics for read.c
to insert the macro name. Free macro_entry on error.
(macro_expand): Pass macro_entry to macro_epand_body. Don't return
when encountering an error, just record the fact.
(expand_irp): Don't return when encountering an error, just record
the fact.
* macro.h (macro_struct): New members name, file, and line.
(define_macro): Add file and line number parameters.
* read.c (s_macro): Pass file and line to define_macro. Tag warning
regarding pseudo-op redefinition with the file/line that macro
definition started at.
2005-04-22 Bob Wilson <bob.wilson@acm.org>
* config/tc-xtensa.c (LOOKAHEAD_ALIGNER): Delete macro.

View File

@ -75,7 +75,7 @@ static int do_formals (macro_entry *, int, sb *);
static int get_apost_token (int, sb *, sb *, int);
static int sub_actual (int, sb *, sb *, struct hash_control *, int, sb *, int);
static const char *macro_expand_body
(sb *, sb *, formal_entry *, struct hash_control *, int);
(sb *, sb *, formal_entry *, struct hash_control *, const macro_entry *);
static const char *macro_expand (int, sb *, macro_entry *, sb *);
static void free_macro(macro_entry *);
@ -471,6 +471,7 @@ static int
do_formals (macro_entry *macro, int idx, sb *in)
{
formal_entry **p = &macro->formals;
const char *name;
idx = sb_skip_white (idx, in);
while (idx < in->len)
@ -501,7 +502,15 @@ do_formals (macro_entry *macro, int idx, sb *in)
}
/* Add to macro's hash table. */
hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
name = sb_terminate (&formal->name);
if (! hash_find (macro->formal_hash, name))
hash_jam (macro->formal_hash, name, formal);
else
as_bad_where (macro->file,
macro->line,
_("A parameter named `%s' already exists for macro `%s'"),
name,
macro->name);
formal->index = macro->formal_count++;
cidx = idx;
@ -519,7 +528,6 @@ do_formals (macro_entry *macro, int idx, sb *in)
if (macro_mri)
{
formal_entry *formal;
const char *name;
/* Add a special NARG formal, which macro_expand will set to the
number of arguments. */
@ -539,6 +547,12 @@ do_formals (macro_entry *macro, int idx, sb *in)
sb_add_string (&formal->name, name);
/* Add to macro's hash table. */
if (hash_find (macro->formal_hash, name))
as_bad_where (macro->file,
macro->line,
_("Reserved word `%s' used as parameter in macro `%s'"),
name,
macro->name);
hash_jam (macro->formal_hash, name, formal);
formal->index = NARG_INDEX;
@ -555,15 +569,19 @@ do_formals (macro_entry *macro, int idx, sb *in)
const char *
define_macro (int idx, sb *in, sb *label,
int (*get_line) (sb *), const char **namep)
int (*get_line) (sb *),
char *file, unsigned int line,
const char **namep)
{
macro_entry *macro;
sb name;
const char *namestr;
const char *error = NULL;
macro = (macro_entry *) xmalloc (sizeof (macro_entry));
sb_new (&macro->sub);
sb_new (&name);
macro->file = file;
macro->line = line;
macro->formal_count = 0;
macro->formals = 0;
@ -571,17 +589,19 @@ define_macro (int idx, sb *in, sb *label,
idx = sb_skip_white (idx, in);
if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
return _("unexpected end of file in macro definition");
error = _("unexpected end of file in macro `%s' definition");
if (label != NULL && label->len != 0)
{
sb_add_sb (&name, label);
macro->name = sb_terminate (&name);
if (idx < in->len && in->ptr[idx] == '(')
{
/* It's the label: MACRO (formals,...) sort */
idx = do_formals (macro, idx + 1, in);
if (idx >= in->len || in->ptr[idx] != ')')
return _("missing ) after formals");
idx = sb_skip_white (idx + 1, in);
if (idx < in->len && in->ptr[idx] == ')')
idx = sb_skip_white (idx + 1, in);
else if (!error)
error = _("missing `)' after formals in macro definition `%s'");
}
else
{
@ -594,8 +614,9 @@ define_macro (int idx, sb *in, sb *label,
int cidx;
idx = get_token (idx, in, &name);
macro->name = sb_terminate (&name);
if (name.len == 0)
return _("Missing macro name");
error = _("Missing macro name");
cidx = sb_skip_white (idx, in);
idx = sb_skip_comma (cidx, in);
if (idx == cidx || idx < in->len)
@ -603,23 +624,26 @@ define_macro (int idx, sb *in, sb *label,
else
idx = cidx;
}
if (idx < in->len)
return _("Bad macro parameter list");
if (!error && idx < in->len)
error = _("Bad parameter list for macro `%s'");
/* And stick it in the macro hash table. */
for (idx = 0; idx < name.len; idx++)
name.ptr[idx] = TOLOWER (name.ptr[idx]);
namestr = sb_terminate (&name);
if (hash_find (macro_hash, namestr))
return _("Macro with this name was already defined");
hash_jam (macro_hash, namestr, (PTR) macro);
macro_defined = 1;
if (hash_find (macro_hash, macro->name))
error = _("Macro `%s' was already defined");
if (!error)
error = hash_jam (macro_hash, macro->name, (PTR) macro);
if (namep != NULL)
*namep = namestr;
*namep = macro->name;
return NULL;
if (!error)
macro_defined = 1;
else
free_macro (macro);
return error;
}
/* Scan a token, and then skip KIND. */
@ -687,16 +711,16 @@ sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash,
static const char *
macro_expand_body (sb *in, sb *out, formal_entry *formals,
struct hash_control *formal_hash, int locals)
struct hash_control *formal_hash, const macro_entry *macro)
{
sb t;
int src = 0;
int inquote = 0;
int src = 0, inquote = 0, macro_line = 0;
formal_entry *loclist = NULL;
const char *err = NULL;
sb_new (&t);
while (src < in->len)
while (src < in->len && !err)
{
if (in->ptr[src] == '&')
{
@ -711,7 +735,8 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
else
{
/* FIXME: Why do we do this? */
/* At least in alternate mode this seems correct. */
/* At least in alternate mode this seems correct; without this
one can't append a literal to a parameter. */
src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
}
}
@ -726,10 +751,12 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
{
sb_add_char (out, in->ptr[src++]);
}
if (in->ptr[src] == ')')
if (src < in->len)
src++;
else if (!macro)
err = _("missing `)'");
else
return _("misplaced `)'");
as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
}
else if (src < in->len && in->ptr[src] == '@')
{
@ -784,7 +811,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
|| ! macro_strip_at
|| (src > 0 && in->ptr[src - 1] == '@')))
{
if (! locals
if (! macro
|| src + 5 >= in->len
|| strncasecmp (in->ptr + src, "LOCAL", 5) != 0
|| ! ISWHITE (in->ptr[src + 5]))
@ -796,31 +823,43 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
}
else
{
formal_entry *f;
src = sb_skip_white (src + 5, in);
while (in->ptr[src] != '\n')
{
static int loccnt;
char buf[20];
const char *err;
const char *name;
formal_entry *f;
f = (formal_entry *) xmalloc (sizeof (formal_entry));
sb_new (&f->name);
sb_new (&f->def);
sb_new (&f->actual);
f->index = LOCAL_INDEX;
f->next = loclist;
loclist = f;
src = get_token (src, in, &f->name);
++loccnt;
sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", loccnt);
sb_add_string (&f->actual, buf);
name = sb_terminate (&f->name);
if (! hash_find (formal_hash, name))
{
static int loccnt;
char buf[20];
err = hash_jam (formal_hash, sb_terminate (&f->name), f);
if (err != NULL)
return err;
sb_new (&f->def);
sb_new (&f->actual);
f->index = LOCAL_INDEX;
f->next = loclist;
loclist = f;
sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt);
sb_add_string (&f->actual, buf);
err = hash_jam (formal_hash, name, f);
if (err != NULL)
break;
}
else
{
as_bad_where (macro->file,
macro->line + macro_line,
_("`%s' was already used as parameter (or another local) name"),
name);
sb_kill (&f->name);
free (f);
}
src = sb_skip_comma (src, in);
}
@ -880,6 +919,8 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
}
else
{
if (in->ptr[src] == '\n')
++macro_line;
sb_add_char (out, in->ptr[src++]);
}
}
@ -901,7 +942,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
loclist = f;
}
return NULL;
return err;
}
/* Assign values to the formal parameters of a macro, and expand the
@ -1060,9 +1101,7 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out)
sb_add_string (&ptr->actual, buffer);
}
err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, 1);
if (err != NULL)
return err;
err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m);
/* Discard any unnamed formal arguments. */
if (macro_mri)
@ -1087,9 +1126,10 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out)
}
sb_kill (&t);
macro_number++;
if (!err)
macro_number++;
return NULL;
return err;
}
/* Check for a macro. If one is found, put the expansion into
@ -1231,8 +1271,6 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
{
/* Expand once with a null string. */
err = macro_expand_body (&sub, out, &f, h, 0);
if (err != NULL)
return err;
}
else
{
@ -1261,7 +1299,7 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
}
err = macro_expand_body (&sub, out, &f, h, 0);
if (err != NULL)
return err;
break;
if (!irpc)
idx = sb_skip_comma (idx, in);
else
@ -1272,5 +1310,5 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
hash_die (h);
sb_kill (&sub);
return NULL;
return err;
}

View File

@ -60,6 +60,9 @@ typedef struct macro_struct
int formal_count; /* Number of formal args. */
formal_entry *formals; /* Pointer to list of formal_structs. */
struct hash_control *formal_hash; /* Hash table of formals. */
const char *name; /* Macro name. */
char *file; /* File the macro was defined in. */
unsigned int line; /* Line number of definition. */
} macro_entry;
/* Whether any macros have been defined. */
@ -76,7 +79,7 @@ extern void macro_init
extern void macro_set_alternate (int);
extern void macro_mri_mode (int);
extern const char *define_macro
(int, sb *, sb *, int (*) (sb *), const char **);
(int, sb *, sb *, int (*) (sb *), char *, unsigned int, const char **);
extern int check_macro (const char *, sb *, const char **, macro_entry **);
extern void delete_macro (const char *);
extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *));

View File

@ -2338,9 +2338,9 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
if (line_label != NULL)
sb_add_string (&label, S_GET_NAME (line_label));
err = define_macro (0, &s, &label, get_line_sb, &name);
err = define_macro (0, &s, &label, get_line_sb, file, line, &name);
if (err != NULL)
as_bad_where (file, line, "%s", err);
as_bad_where (file, line, err, name);
else
{
if (line_label != NULL)
@ -2355,7 +2355,9 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
|| (!flag_m68k_mri
&& *name == '.'
&& hash_find (po_hash, name + 1) != NULL))
as_warn (_("attempt to redefine pseudo-op `%s' ignored"),
as_warn_where (file,
line,
_("attempt to redefine pseudo-op `%s' ignored"),
name);
}

View File

@ -1,3 +1,9 @@
2005-04-25 Jan Beulich <jbeulich@novell.com>
* gas/macros/badarg.s: Add tests for collisions between/among macro
parameters and local symbols.
* gas/macros/badarg.l: Adjust.
2005-04-20 Jan Beulich <jbeulich@novell.com>
* gas/elf/struct.s: Adjust to not get into alignment issues.

View File

@ -5,3 +5,6 @@
.*:10: Error: .*
.*:13: Error: .*
.*:16: Error: .*
.*:19: Error: .*
.*:25: Error: .*
.*:30: Error: .*

View File

@ -15,3 +15,20 @@
.macro m4,,arg2
.endm
.macro m5,arg,arg
.endm
.altmacro
.macro m6,arg
local arg
.endm
.macro m7
local arg
local arg
.endm
m6
m7