summaryrefslogtreecommitdiff
path: root/asm
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2019-10-23 12:59:06 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2019-10-23 12:59:06 -0700
commite91f5cc1322eed4da0de81656276e021bf352c3d (patch)
tree0043393b0084e7e50ae31909d29b3ab98a486803 /asm
parent0741eb600481a97c3baddb290e0ab1a33a9e4921 (diff)
downloadnasm-e91f5cc1322eed4da0de81656276e021bf352c3d.tar.gz
preproc: fix %undef of macro aliases, and add %ifdefalias
Macro aliases can legitimately point to nonexistent macros. Furthermore, %undef should remove the pointed-at macro, not the alias. This led to an infinite loop in the existing code; fix that. Add an %ifdefalias directive to test for the existence of an alias. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Diffstat (limited to 'asm')
-rw-r--r--asm/pptok.dat1
-rw-r--r--asm/preproc.c72
2 files changed, 38 insertions, 35 deletions
diff --git a/asm/pptok.dat b/asm/pptok.dat
index d2f361c8..b6285c36 100644
--- a/asm/pptok.dat
+++ b/asm/pptok.dat
@@ -44,6 +44,7 @@
*
*ctx
*def
+*defalias
*empty
*env
*id
diff --git a/asm/preproc.c b/asm/preproc.c
index c0234260..41a7c6fb 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -638,6 +638,8 @@ static Token *delete_Token(Token *t);
static Token *steal_Token(Token *dst, Token *src);
static const struct use_package *
get_use_pkg(Token *t, const char *dname, const char **name);
+static void mark_smac_params(Token *tline, const SMacro *tmpl,
+ enum pp_token_type type);
/* Safe test for token type, false on x == NULL */
static inline bool tok_type(const Token *x, enum pp_token_type t)
@@ -2278,30 +2280,15 @@ FILE *pp_input_fopen(const char *filename, enum file_flags mode)
*
* Note that this is also called with nparam zero to resolve
* `ifdef'.
- *
- * If you already know which context macro belongs to, you can pass
- * the context pointer as first parameter; if you won't but name begins
- * with %$ the context will be automatically computed. If all_contexts
- * is true, macro will be searched in outer contexts as well.
*/
static bool
-smacro_defined(Context * ctx, const char *name, int nparam, SMacro ** defn,
+smacro_defined(Context *ctx, const char *name, int nparam, SMacro **defn,
bool nocase, bool find_alias)
{
struct hash_table *smtbl;
SMacro *m;
- if (ctx) {
- smtbl = &ctx->localmac;
- } else if (name[0] == '%' && name[1] == '$') {
- if (cstk)
- ctx = get_ctx(name, &name);
- if (!ctx)
- return false; /* got to return _something_ */
- smtbl = &ctx->localmac;
- } else {
- smtbl = &smacros;
- }
+ smtbl = ctx ? &ctx->localmac : &smacros;
restart:
m = (SMacro *) hash_findix(smtbl, name);
@@ -2442,6 +2429,13 @@ static enum cond_state if_condition(Token * tline, enum preproc_token ct)
break;
case PP_IFDEF:
+ case PP_IFDEFALIAS:
+ {
+ bool alias = cond == PP_IFDEFALIAS;
+ SMacro *smac;
+ Context *ctx;
+ const char *mname;
+
j = false; /* have we matched yet? */
while (tline) {
tline = skip_white(tline);
@@ -2451,11 +2445,18 @@ static enum cond_state if_condition(Token * tline, enum preproc_token ct)
dname);
goto fail;
}
- if (smacro_defined(NULL, tok_text(tline), 0, NULL, true, false))
+
+ mname = tok_text(tline);
+ ctx = get_ctx(mname, &mname);
+ if (smacro_defined(ctx, mname, 0, &smac, true, alias)
+ && smac->alias == alias) {
j = true;
+ break;
+ }
tline = tline->next;
}
break;
+ }
case PP_IFENV:
tline = expand_smacro(tline);
@@ -2932,6 +2933,8 @@ static SMacro *define_smacro(const char *mname, bool casesense,
if (tmpl) {
defining_alias = tmpl->alias;
nparam = tmpl->nparam;
+ if (nparam && !defining_alias)
+ mark_smac_params(expansion, tmpl, 0);
}
while (1) {
@@ -3022,14 +3025,14 @@ static void undef_smacro(const char *mname, bool undefalias)
while ((s = *sp) != NULL) {
if (!mstrcmp(s->name, mname, s->casesense)) {
if (s->alias && !undefalias) {
- if (!do_aliases)
- continue;
- if (s->in_progress) {
- nasm_nonfatal("macro alias loop");
- } else {
- s->in_progress = true;
- undef_smacro(tok_text(s->expansion), false);
- s->in_progress = false;
+ if (do_aliases) {
+ if (s->in_progress) {
+ nasm_nonfatal("macro alias loop");
+ } else {
+ s->in_progress = true;
+ undef_smacro(tok_text(s->expansion), false);
+ s->in_progress = false;
+ }
}
} else {
if (list_option('d'))
@@ -3037,10 +3040,10 @@ static void undef_smacro(const char *mname, bool undefalias)
ctx, s);
*sp = s->next;
free_smacro(s);
+ continue;
}
- } else {
- sp = &s->next;
}
+ sp = &s->next;
}
}
}
@@ -3213,6 +3216,8 @@ get_use_pkg(Token *t, const char *dname, const char **name)
* is 0, create smac param tokens, otherwise use the type specified;
* normally this is used for TOK_XDEF_PARAM, which is used to protect
* parameter tokens during expansion during %xdefine.
+ *
+ * tmpl may not be NULL here.
*/
static void mark_smac_params(Token *tline, const SMacro *tmpl,
enum pp_token_type type)
@@ -3222,9 +3227,6 @@ static void mark_smac_params(Token *tline, const SMacro *tmpl,
Token *t;
int i;
- if (!nparam)
- return;
-
list_for_each(t, tline) {
if (t->type != TOK_ID && t->type != TOK_XDEF_PARAM)
continue;
@@ -4052,13 +4054,14 @@ issue_error:
{
SMacro tmpl;
Token **lastp;
+ int nparam;
if (!(mname = get_id(&tline, dname)))
goto done;
nasm_zero(tmpl);
lastp = &tline->next;
- parse_smacro_template(&lastp, &tmpl);
+ nparam = parse_smacro_template(&lastp, &tmpl);
tline = *lastp;
*lastp = NULL;
@@ -4082,11 +4085,10 @@ issue_error:
} else {
if (op == PP_XDEFINE) {
/* Protect macro parameter tokens */
- mark_smac_params(tline, &tmpl, TOK_XDEF_PARAM);
+ if (nparam)
+ mark_smac_params(tline, &tmpl, TOK_XDEF_PARAM);
tline = expand_smacro(tline);
}
-
- mark_smac_params(tline, &tmpl, 0);
/* NB: Does this still make sense? */
macro_start = reverse_tokens(tline);
}