aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2020-07-05 03:39:04 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2020-07-05 03:39:04 -0700
commit122c5fb75986adc37dfb147cc2a613e3ebc66e80 (patch)
treef2c228ed21a2c1ae4cc7f696b0e554fcc9b7ee1a
parent5b7369d7e0e256684bc92ab2ec8a822d9eb32e32 (diff)
downloadnasm-122c5fb75986adc37dfb147cc2a613e3ebc66e80.tar.gz
nasm-122c5fb75986adc37dfb147cc2a613e3ebc66e80.tar.xz
nasm-122c5fb75986adc37dfb147cc2a613e3ebc66e80.zip
preproc: handle %+ pasting after empty expansions
%+ tokens can end up next to each other, or at the beginning or the end of an expansion if we try to paste the output of empty macros. This is perhaps particularly likely to happen in %[] expressions. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r--asm/preproc.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/asm/preproc.c b/asm/preproc.c
index 5cb92879..81c72042 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -4726,9 +4726,8 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
if (!handle_explicit)
break;
- /* Left pasting token is start of line */
+ /* Left pasting token is start of line, just drop %+ */
if (!prev_nonspace) {
- nasm_nonfatal("No lvalue found on pasting");
tok = delete_Token(tok);
break;
}
@@ -4741,28 +4740,25 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
/* Delete leading whitespace */
next = zap_white(t->next);
- /* Delete the %+ token itself */
- nasm_assert(next == tok);
- next = delete_Token(next);
-
- /* Delete trailing whitespace */
- next = zap_white(next);
+ /*
+ * Delete the %+ token itself, followed by any whitespace.
+ * In a sequence of %+ ... %+ ... %+ pasting sequences where
+ * some expansions in the middle have ended up empty,
+ * we can end up having multiple %+ tokens in a row;
+ * just drop whem in that case.
+ */
+ while (next) {
+ if (next->type == TOK_PASTE || next->type == TOK_WHITESPACE)
+ next = delete_Token(next);
+ else
+ break;
+ }
/*
- * No ending token, this might happen in two
- * cases
- *
- * 1) There indeed no right token at all
- * 2) There is a bare "%define ID" statement,
- * and @ID does expand to whitespace.
- *
- * So technically we need to do a grammar analysis
- * in another stage of parsing, but for now lets don't
- * change the behaviour people used to. Simply allow
- * whitespace after paste token.
+ * Nothing after? Just leave the existing token.
*/
if (!next) {
- *prev_nonspace = tok = NULL; /* End of line */
+ t->next = tok = NULL; /* End of line */
break;
}