diff options
author | H. Peter Anvin <hpa@zytor.com> | 2018-12-10 21:28:59 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2018-12-10 21:28:59 -0800 |
commit | 36e3c707908738ce15dfc75b5a6d57c3e2791e2a (patch) | |
tree | 4b5f1276ff015d6e204b28f2ac245c4a3dc0e8bf | |
parent | 2bc04aff90f0d6f2ce66158600592977691619f5 (diff) | |
parent | 54aac9d3c1b501050e6e75823317a4e34d6b2066 (diff) | |
download | nasm-36e3c707908738ce15dfc75b5a6d57c3e2791e2a.tar.gz |
Merge remote-tracking branch 'origin/nasm-2.14.xx'
Resolved Conflicts:
asm/labels.c
include/error.h
version
-rw-r--r-- | asm/labels.c | 76 | ||||
-rw-r--r-- | asm/nasm.c | 27 | ||||
-rw-r--r-- | doc/changes.src | 6 | ||||
-rw-r--r-- | include/error.h | 5 |
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); } /* @@ -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, ¤tfile); 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 */ |