From e99a946390e561804bf624a1e67f25ae34b13dfd Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin (Intel)" Date: Tue, 30 Jun 2020 11:51:41 -0700 Subject: preproc: fix %{:} macro operand ranges Fix the handling of %{:} macro operands. Use the same code for expanding the subarguments as for normal arguments. This (hopefully) resolves the following bug reports: BR 3392611, BR 3392686, BR 3392688 Reported-by: Reported-by: Jasper Lievisse Adriaanse Reported-by: Jason Hood Signed-off-by: H. Peter Anvin (Intel) --- asm/preproc.c | 87 ++++++++++----------------------- test/emptyarg.asm | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 164 insertions(+), 63 deletions(-) mode change 120000 => 100644 test/emptyarg.asm diff --git a/asm/preproc.c b/asm/preproc.c index 14ca17d3..2165fa12 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -4835,17 +4835,15 @@ static int mmac_rotate(const MMacro *mac, unsigned int n) /* * expands to a list of tokens from %{x:y} */ -static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last) +void expand_mmac_params_range(MMacro *mac, Token *tline, Token ***tail) { - Token *t = tline, **tt, *tm, *head; - char *pos; - int fst, lst, j, i; - - pos = strchr(tok_text(tline), ':'); - nasm_assert(pos); + Token *t; + const char *arg = tok_text(tline) + 1; + int fst, lst, incr, n; + int parsed; - lst = atoi(pos + 1); - fst = atoi(tok_text(tline) + 1); + parsed = sscanf(arg, "%d:%d", &fst, &lst); + nasm_assert(parsed == 2); /* * only macros params are accounted so @@ -4863,56 +4861,28 @@ static Token *expand_mmac_params_range(MMacro *mac, Token *tline, Token ***last) fst = fst < 0 ? fst + (int)mac->nparam + 1: fst; lst = lst < 0 ? lst + (int)mac->nparam + 1: lst; - /* count from zero */ - fst--, lst--; - /* - * It will be at least one token. Note we - * need to scan params until separator, otherwise - * only first token will be passed. + * It will be at least one parameter, as we can loop + * in either direction. */ - j = (fst + mac->rotate) % mac->nparam; - tm = mac->params[j+1]; - if (!tm) - goto err; - head = dup_Token(NULL, tm); - tt = &head->next, tm = tm->next; - while (tok_isnt(tm, ',')) { - t = dup_Token(NULL, tm); - *tt = t, tt = &t->next, tm = tm->next; - } + incr = (fst < lst) ? 1 : -1; - if (fst < lst) { - for (i = fst + 1; i <= lst; i++) { - t = make_tok_char(NULL, ','); - *tt = t, tt = &t->next; - j = (i + mac->rotate) % mac->nparam; - tm = mac->params[j+1]; - while (tok_isnt(tm, ',')) { - t = dup_Token(NULL, tm); - *tt = t, tt = &t->next, tm = tm->next; - } - } - } else { - for (i = fst - 1; i >= lst; i--) { - t = make_tok_char(NULL, ','); - *tt = t, tt = &t->next; - j = (i + mac->rotate) % mac->nparam; - tm = mac->params[j+1]; - while (!tok_isnt(tm, ',')) { - t = dup_Token(NULL, tm); - *tt = t, tt = &t->next, tm = tm->next; - } - } + while (true) { + n = mmac_rotate(mac, fst); + dup_tlistn(mac->params[n], mac->paramlen[n], tail); + if (fst == lst) + break; + t = make_tok_char(NULL, ','); + **tail = t; + *tail = &t->next; + fst += incr; } - *last = tt; - return head; + return; err: - nasm_nonfatal("`%%{%s}': macro parameters out of range", - tok_text(tline) + 1); - return NULL; + nasm_nonfatal("`%%{%s}': macro parameters out of range", arg); + return; } /* @@ -4963,16 +4933,9 @@ static Token *expand_mmac_params(Token * tline) } if (strchr(text, ':')) { - /* - * seems we have a parameters range here - */ - Token *head, **last; - head = expand_mmac_params_range(mac, t, &last); - if (head) { - *tail = head; - *last = tline; - text = NULL; - } + /* It is a range */ + expand_mmac_params_range(mac, t, &tail); + text = NULL; break; } diff --git a/test/emptyarg.asm b/test/emptyarg.asm deleted file mode 120000 index 0627dfae..00000000 --- a/test/emptyarg.asm +++ /dev/null @@ -1 +0,0 @@ -../../nasm-2.14.xx/test/emptyarg.asm \ No newline at end of file diff --git a/test/emptyarg.asm b/test/emptyarg.asm new file mode 100644 index 00000000..f164fe41 --- /dev/null +++ b/test/emptyarg.asm @@ -0,0 +1,139 @@ +%define EMPTY + +%macro bar 1 + db "bar", __LINE__, %0, %1 +%endmacro + +%macro baz 2 + db "baz", __LINE__, %0, %1, %2 +%endmacro + +%macro nothing 0 + db "nothing", __LINE__, %0 +%endmacro + +%macro xyzzy 1-2 + db "xyzzy", __LINE__, %0, %1, %2, %3 +%endmacro + +%macro vararg 0-* + db "vararg", __LINE__, %0 + %assign %%i 1 + %rep %0 + db "vararg arg ", %%i, %1 + %rotate 1 + %assign %%i %%i + 1 + %endrep +%endmacro + +%macro defargs 1-5 def2, def3, def4, def5 + db "defargs", __LINE__, %0, %1, %2, %3, %4, %5 +%endmacro + +%macro ivar 1 + vararg %1 +%endmacro + +%macro foo 1-2 + db "foo", __LINE__, %0, %1, %2 + bar %2 + bar {%2} + bar %2, + bar {%2}, + baz %1,%2 + baz {%1},{%2} + nothing %1 + nothing %2 + xyzzy "meep",%1,%2, + xyzzy "meep","meep",%1,%2 + xyzzy "alpha","bravo", + xyzzy "with","empty",EMPTY +%endmacro + +%macro prange1 2-3 + db %{1:2}, 0%3 +%endmacro + +%macro prange2 1-3 'two', 'three' + db %{1:3} +%endmacro + + db 4, + nothing + nothing 1 + nothing ; foo + nothing EMPTY + +flup: foo 1,2 + foo 3 + bar + bar EMPTY + foo 6, + foo 6, ; With space/comment + foo 6,EMPTY + baz 8,EMPTY + foo 6,{} + foo ,5 + + xyzzy 13,14,15, + xyzzy 13,14,15,EMPTY + xyzzy 20,21 + xyzzy 22,23, + xyzzy 24,25,EMPTY + xyzzy 26,27,, + xyzzy 28,29,EMPTY,EMPTY + + vararg + vararg EMPTY + vararg , + vararg 10 + vararg 11, + vararg 12,EMPTY + vararg 13,14,15, + vararg 13,14,15,EMPTY + vararg 20,21 + vararg 22,23, + vararg 24,25,EMPTY + vararg 26,27,, + vararg 28,29,EMPTY,EMPTY + + ivar {} + ivar {EMPTY} + ivar EMPTY + ivar , + ivar {,} + ivar {60} + ivar {61,} + ivar {62,EMPTY} + ivar {63,64,65,} + ivar {63,64,65,EMPTY} + ivar {70,71} + ivar {72,73,} + ivar {74,75,EMPTY} + ivar {76,77,,} + ivar {78,79,EMPTY,EMPTY} + + defargs EMPTY + defargs 91 + defargs 91,92 + defargs 91,92,93 + defargs 91,92,93,94 + defargs 91,92,93,94,95 + defargs , + defargs 91, + defargs 91,92, + defargs 91,92,93, + defargs 91,92,93,94, + defargs 91,92,93,94,95, + + prange1 101 + prange1 101, 102 + prange1 101, 102, 103 + prange2 121 + prange2 121, 122 + prange2 121, 122, 123 + prange2 {121} + prange2 {121,121} + prange2 {121},{122} + prange2 {121},122,{123} + prange2 121,{122,122},123 -- cgit v1.2.1