aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-12-10 21:28:59 -0800
committerH. Peter Anvin <hpa@zytor.com>2018-12-10 21:28:59 -0800
commit36e3c707908738ce15dfc75b5a6d57c3e2791e2a (patch)
tree4b5f1276ff015d6e204b28f2ac245c4a3dc0e8bf
parent2bc04aff90f0d6f2ce66158600592977691619f5 (diff)
parent54aac9d3c1b501050e6e75823317a4e34d6b2066 (diff)
downloadnasm-36e3c707908738ce15dfc75b5a6d57c3e2791e2a.tar.gz
nasm-36e3c707908738ce15dfc75b5a6d57c3e2791e2a.tar.xz
nasm-36e3c707908738ce15dfc75b5a6d57c3e2791e2a.zip
Merge remote-tracking branch 'origin/nasm-2.14.xx'
Resolved Conflicts: asm/labels.c include/error.h version
-rw-r--r--asm/labels.c76
-rw-r--r--asm/nasm.c27
-rw-r--r--doc/changes.src6
-rw-r--r--include/error.h5
4 files changed, 88 insertions, 26 deletions
diff --git a/asm/labels.c b/asm/labels.c
index 4e69d99a..cffe1027 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -109,9 +109,11 @@ union label { /* actual label structures */
int32_t subsection; /* Available for ofmt->herelabel() */
int64_t offset;
int64_t size;
+ int64_t defined; /* 0 if undefined, passn+1 for when defn seen */
char *label, *mangled, *special;
+ const char *def_file; /* Where defined */
+ int32_t def_line;
enum label_type type, mangled_type;
- bool defined;
} defn;
struct {
int32_t movingon;
@@ -369,7 +371,7 @@ handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset)
location.offset = *offset;
} else {
/* Keep a separate offset for the new segment */
- *offset = switch_segment(newseg);
+ *offset = switch_segment(newseg);
}
}
}
@@ -433,6 +435,13 @@ void define_label(const char *label, int32_t segment,
union label *lptr;
bool created, changed;
int64_t size;
+ int64_t lastdef;
+
+ /*
+ * The backend may invoke this before pass 1, so treat that as
+ * a special "pass".
+ */
+ const int64_t lpass = pass0 + 1;
/*
* Phase errors here can be one of two types: a new label appears,
@@ -441,17 +450,26 @@ void define_label(const char *label, int32_t segment,
*/
lptr = find_label(label, true, &created);
+ lastdef = lptr->defn.defined;
+
if (segment) {
/* We are actually defining this label */
- if (lptr->defn.type == LBL_EXTERN) /* auto-promote EXTERN to GLOBAL */
+ if (lptr->defn.type == LBL_EXTERN) {
+ /* auto-promote EXTERN to GLOBAL */
lptr->defn.type = LBL_GLOBAL;
+ lastdef = 0; /* We are "re-creating" this label */
+ }
} else {
/* It's a pseudo-segment (extern, common) */
segment = lptr->defn.segment ? lptr->defn.segment : seg_alloc();
}
- if (lptr->defn.defined || lptr->defn.type == LBL_BACKEND) {
- /* We have seen this on at least one previous pass */
+ if (lastdef || lptr->defn.type == LBL_BACKEND) {
+ /*
+ * We have seen this on at least one previous pass, or
+ * potentially earlier in this same pass (in which case we
+ * will probably error out further down.)
+ */
mangle_label_name(lptr);
handle_herelabel(lptr, &segment, &offset);
}
@@ -469,27 +487,51 @@ void define_label(const char *label, int32_t segment,
size = 0; /* This is a hack... */
}
- changed = created || !lptr->defn.defined ||
+ changed = created || !lastdef ||
lptr->defn.segment != segment ||
- lptr->defn.offset != offset || lptr->defn.size != size;
+ lptr->defn.offset != offset ||
+ lptr->defn.size != size;
global_offset_changed += changed;
- /*
- * This probably should be ERR_NONFATAL, but not quite yet. As a
- * special case, LBL_SPECIAL symbols are allowed to be changed
- * even during the last pass.
- */
- if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) {
- nasm_warn("label `%s' %s during code generation",
- lptr->defn.label, created ? "defined" : "changed");
+ if (changed) {
+ if (lastdef == lpass) {
+ int32_t saved_line = 0;
+ const char *saved_fname = NULL;
+
+ /*
+ * Defined elsewhere in the program, seen in this pass.
+ */
+ nasm_error(ERR_NONFATAL,
+ "label `%s' inconsistently redefined",
+ lptr->defn.label);
+
+ src_get(&saved_line, &saved_fname);
+ src_set(lptr->defn.def_line, lptr->defn.def_file);
+ nasm_error(ERR_NOTE, "label `%s' originally defined here",
+ lptr->defn.label);
+ src_set(saved_line, saved_fname);
+ } else if (pass0 > 1 && lptr->defn.type != LBL_SPECIAL) {
+ /*
+ * This probably should be ERR_NONFATAL, but not quite yet. As a
+ * special case, LBL_SPECIAL symbols are allowed to be changed
+ * even during the last pass.
+ */
+ nasm_warn("label `%s' %s during code generation",
+ lptr->defn.label,
+ created ? "defined" : "changed");
+ }
}
lptr->defn.segment = segment;
lptr->defn.offset = offset;
lptr->defn.size = size;
- lptr->defn.defined = true;
+ lptr->defn.defined = lpass;
+
+ if (changed || lastdef != lpass)
+ src_get(&lptr->defn.def_line, &lptr->defn.def_file);
- out_symdef(lptr);
+ if (lastdef != lpass)
+ out_symdef(lptr);
}
/*
diff --git a/asm/nasm.c b/asm/nasm.c
index eb6f4760..4c4d6de4 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -1756,7 +1756,7 @@ static void nasm_verror_gnu(int severity, const char *fmt, va_list ap)
if (!skip_this_pass(severity)) {
if (!lineno)
- fprintf(error_file, "%s:", currentfile ? currentfile : "nasm");
+ fprintf(error_file, "%s: ", currentfile ? currentfile : "nasm");
else
fprintf(error_file, "%s:%"PRId32": ", currentfile, lineno);
}
@@ -1791,10 +1791,10 @@ static void nasm_verror_vc(int severity, const char *fmt, va_list ap)
src_get(&lineno, &currentfile);
if (!skip_this_pass(severity)) {
- if (currentfile) {
+ if (lineno) {
fprintf(error_file, "%s(%"PRId32") : ", currentfile, lineno);
} else {
- fputs("nasm: ", error_file);
+ fprintf(error_file , "%s : ", currentfile ? currentfile : "nasm");
}
}
@@ -1871,11 +1871,19 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
{
char msg[1024];
const char *pfx;
+ bool warn_is_err = warning_is_error(severity);
+ bool warn_is_other = WARN_IDX(severity) == ERR_WARN_OTHER;
switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) {
- case ERR_WARNING:
- pfx = "warning: ";
+ case ERR_NOTE:
+ pfx = "note: ";
break;
+ case ERR_WARNING:
+ if (!warn_is_err) {
+ pfx = "warning: ";
+ break;
+ }
+ /* fall through */
case ERR_NONFATAL:
pfx = "error: ";
break;
@@ -1894,9 +1902,11 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
}
vsnprintf(msg, sizeof msg - 64, fmt, args);
- if (is_valid_warning(severity) && WARN_IDX(severity) != ERR_WARN_OTHER) {
+ if (is_valid_warning(severity) && (warn_is_err || !warn_is_other)) {
char *p = strchr(msg, '\0');
- snprintf(p, 64, " [-w+%s]", warnings[WARN_IDX(severity)].name);
+ snprintf(p, 64, " [-w+%s%s]",
+ warn_is_err ? "error=" : "",
+ warnings[WARN_IDX(severity)].name);
}
if (!skip_this_pass(severity))
@@ -1921,6 +1931,7 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
preproc->error_list_macros(severity);
switch (severity & ERR_MASK) {
+ case ERR_NOTE:
case ERR_DEBUG:
/* no further action, by definition */
break;
@@ -1957,6 +1968,8 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
}
exit(3);
break;
+ default:
+ break; /* ??? */
}
}
diff --git a/doc/changes.src b/doc/changes.src
index 1bc8f2aa..8e0bc060 100644
--- a/doc/changes.src
+++ b/doc/changes.src
@@ -31,6 +31,12 @@ filename. See \k{opt-MD}.
\b Fix \c{-E} in combination with \c{-MD}. See \k{opt-E}.
+\b Fix missing errors on redefined labels; would cause convergence
+failure instead which is very slow and not easy to debug.
+
+\b Duplicate definitions of the same label \e{with the same value} is now
+explicitly permitted (2.14 would allow it in some circumstances.)
+
\S{cl-2.14} Version 2.14
\b Changed \c{-I} option semantics by adding a trailing path separator
diff --git a/include/error.h b/include/error.h
index c87ea68c..5d3dc22e 100644
--- a/include/error.h
+++ b/include/error.h
@@ -73,8 +73,9 @@ static inline vefunc nasm_set_verror(vefunc ve)
*/
#define ERR_DEBUG 0x00000000 /* put out debugging message */
-#define ERR_WARNING 0x00000001 /* warn only: no further action */
-#define ERR_NONFATAL 0x00000002 /* terminate assembly after phase */
+#define ERR_NOTE 0x00000001 /* additional error information */
+#define ERR_WARNING 0x00000002 /* warn only: no further action */
+#define ERR_NONFATAL 0x00000003 /* terminate assembly after phase */
#define ERR_FATAL 0x00000006 /* instantly fatal: exit with error */
#define ERR_PANIC 0x00000007 /* internal error: panic instantly
* and dump core for reference */