From 1b939ecf3d0e937802431fee4c8e0a1954f2d113 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin (Intel)" Date: Wed, 15 Oct 2025 21:09:05 -0700 Subject: [PATCH] errors: add the ability to hold errors, not just warnings Re-introduce ERR_HOLD, which means that an error is treated like a warning except for the last pass, but unlike ERR_PASS2 the error message *will* be issued if another error happens on the same pass, just like warnings. This will be used to improve error messages on instruction mismatch. Signed-off-by: H. Peter Anvin (Intel) --- asm/error.c | 8 ++++++++ asm/nasm.c | 19 +++++++++++-------- asm/preproc.c | 2 +- include/error.h | 1 + 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/asm/error.c b/asm/error.c index 0e17ffef..332f9254 100644 --- a/asm/error.c +++ b/asm/error.c @@ -85,6 +85,14 @@ void nasm_debug_(unsigned int level, const char *fmt, ...) nasm_do_error(ERR_DEBUG, LEVEL(level)); } +/* + * Convenience function for nasm_nonfatal(ERR_HOLD, ...) + */ +void nasm_holderr(const char *fmt, ...) +{ + nasm_do_error(ERR_NONFATAL, ERR_NONFATAL|ERR_HOLD); +} + fatal_func nasm_panic_from_macro(const char *func, const char *file, int line) { if (!func) diff --git a/asm/nasm.c b/asm/nasm.c index 8db100cf..5f7168f3 100644 --- a/asm/nasm.c +++ b/asm/nasm.c @@ -1870,13 +1870,12 @@ static errflags pure_func true_error_type(errflags severity) type = severity & ERR_MASK; - /* Promote warning to error? */ if (type == ERR_WARNING) { + /* Promote warning to error? */ uint8_t state = warning_state[WARN_IDX(severity)]; if ((state & warn_is_err) == warn_is_err) type = ERR_NONFATAL; } - return type; } @@ -2125,6 +2124,7 @@ static void nasm_issue_error(struct nasm_errtext *et) const errflags severity = et->severity; const errflags true_type = et->true_type; const struct src_location where = et->where; + bool buffer = true_type < ERR_NONFATAL || (severity & ERR_HOLD); if (severity & ERR_NO_SEVERITY) pfx = ""; @@ -2167,10 +2167,13 @@ static void nasm_issue_error(struct nasm_errtext *et) here = where.filename ? " here" : " in an unknown location"; } - if (warn_list && true_type < ERR_NONFATAL) { + if (!warn_list) + buffer = false; + + if (buffer) { /* - * Buffer up warnings until we either get an error - * or we are on the code-generation pass. + * Buffer up warnings and held errors until we either get + * an error or we are on the code-generation pass. */ strlist_printf(warn_list, "%s%s%s%s%s%s%s", file, linestr, errfmt->beforemsg, @@ -2180,7 +2183,7 @@ static void nasm_issue_error(struct nasm_errtext *et) * Actually output an error. If we have buffered * warnings, and this is a non-warning, output them now. */ - if (true_type >= ERR_NONFATAL && warn_list) { + if (warn_list) { strlist_write(warn_list, "\n", error_file); strlist_free(&warn_list); } @@ -2216,9 +2219,9 @@ static void nasm_issue_error(struct nasm_errtext *et) if (skip_this_pass(severity)) goto done; - if (true_type >= ERR_FATAL) + if (true_type >= ERR_FATAL) { die_hard(true_type, severity); - else if (true_type >= ERR_NONFATAL) { + } else if (true_type >= ERR_NONFATAL && !buffer) { terminate_after_phase = true; errflags_never |= ERR_UNDEAD; } diff --git a/asm/preproc.c b/asm/preproc.c index cf028e7b..d0d65542 100644 --- a/asm/preproc.c +++ b/asm/preproc.c @@ -6464,7 +6464,7 @@ static SMacro *expand_one_smacro(Token ***tpp) */ while (1) { if (!m) { - nasm_warn(WARN_PP_MACRO_PARAMS_SINGLE|ERR_HOLD, + nasm_warn(WARN_PP_MACRO_PARAMS_SINGLE, "single-line macro `%s' exists, " "but not taking %d parameter%s", mname, nparam, (nparam == 1) ? "" : "s"); diff --git a/include/error.h b/include/error.h index ae69fc84..22c5864a 100644 --- a/include/error.h +++ b/include/error.h @@ -28,6 +28,7 @@ void printf_func(2, 3) nasm_notef(errflags flags, const char *fmt, ...); void printf_func(2, 3) nasm_warn_(errflags flags, const char *fmt, ...); void printf_func(1, 2) nasm_nonfatal(const char *fmt, ...); void printf_func(2, 3) nasm_nonfatalf(errflags flags, const char *fmt, ...); +void printf_func(1, 2) nasm_holderr(const char *fmt, ...); fatal_func printf_func(1, 2) nasm_fatal(const char *fmt, ...); fatal_func printf_func(2, 3) nasm_fatalf(errflags flags, const char *fmt, ...); fatal_func printf_func(1, 2) nasm_critical(const char *fmt, ...);