From 4cf86ddde8cd8655819358ae88c1ff70a2a79713 Mon Sep 17 00:00:00 2001
From: "H. Peter Anvin" <hpa@zytor.com>
Date: Thu, 27 Dec 2018 11:24:17 -0800
Subject: [PATCH] BR 3392539: some errors can "cascade". Allow suppressing if
 dead.

In BR 3392539, the error:

helloW.s:18: error: label `rurt' changed during code generation
[-w+error=label-redef-late]

... occurs a number of times after we have already issued an
error. This is because the erroring instruction computes to a
different size during code generation; this causes each subsequent
label to cause a phase error.

The phase error simply doesn't make much sense to report: if we are
already committed to erroring out, it is more likely an error cascade
rather than an error in its own right, so just suppress it in that
case.

Reported-by: <russvz@comcast.net>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
---
 asm/labels.c    | 2 +-
 asm/nasm.c      | 7 ++++++-
 include/error.h | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/asm/labels.c b/asm/labels.c
index 20107603..4e61fd22 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -529,7 +529,7 @@ void define_label(const char *label, int32_t segment,
          * As a special case, LBL_SPECIAL symbols are allowed to be changed
          * even during the last pass.
          */
-        nasm_error(ERR_WARNING|WARN_LABEL_LATE,
+        nasm_error(ERR_WARNING|WARN_LABEL_LATE|ERR_UNDEAD,
                    "label `%s' %s during code generation",
                    lptr->defn.label, created ? "defined" : "changed");
     }
diff --git a/asm/nasm.c b/asm/nasm.c
index 1c5a5fc5..1037166f 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1775,8 +1775,13 @@ static bool skip_this_pass(int severity)
  */
 static bool is_suppressed(int severity)
 {
+    /* Fatal errors must never be suppressed */
     if ((severity & ERR_MASK) >= ERR_FATAL)
-        return false;           /* Fatal errors can never be suppressed */
+        return false;
+
+    /* This error/warning is pointless if we are dead anyway */
+    if ((severity & ERR_UNDEAD) && terminate_after_phase)
+        return true;
 
     return !(warning_state[warn_index(severity)] & WARN_ST_ENABLED);
 }
diff --git a/include/error.h b/include/error.h
index 477a26d7..433c0680 100644
--- a/include/error.h
+++ b/include/error.h
@@ -76,6 +76,7 @@ static inline vefunc nasm_set_verror(vefunc ve)
 #define ERR_PANIC       0x00000007      /* internal error: panic instantly
                                          * and dump core for reference */
 #define ERR_MASK        0x00000007      /* mask off the above codes */
+#define ERR_UNDEAD	0x00000008      /* skip if we already have errors */
 #define ERR_NOFILE      0x00000010      /* don't give source file name/line */
 #define ERR_HERE	0x00000020      /* point to a specific source location */
 #define ERR_USAGE       0x00000040      /* print a usage message */