summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-13 21:53:31 -0800
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-12-13 21:53:31 -0800
commit723ab481a6550454a6f834bb854e751744ca340a (patch)
treecb217692a76d3dcab83c7ad922e3adca9006dccd
parent6bde2ed8806b3e53657d46b61ee79d7afe5c2e13 (diff)
downloadnasm-mkwarnings.tar.gz
warnings: define warning classes at point of usemkwarnings
It is extremely desirable to allow the user fine-grained control of warnings, but this has been complicated by the fact that a warning class has had to be defined in no less than three places (error.h, error.c, nasmdoc.src) before it can be used in source code. Instead, use a script to define these via magic comments at the point of use. This hopefully will encourage creating new classes as needed. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r--.gitignore3
-rw-r--r--Makefile.in19
-rw-r--r--asm/assemble.c25
-rw-r--r--asm/directiv.c4
-rw-r--r--asm/error.c68
-rw-r--r--asm/float.c30
-rw-r--r--asm/labels.c21
-rw-r--r--asm/nasm.c42
-rw-r--r--asm/parser.c6
-rw-r--r--asm/pragma.c17
-rw-r--r--asm/preproc.c29
-rw-r--r--asm/stdscan.c6
-rwxr-xr-xasm/warnings.pl46
-rw-r--r--doc/Makefile.in2
-rw-r--r--doc/nasmdoc.src77
-rw-r--r--include/error.h49
-rw-r--r--nasmlib/readnum.c8
-rw-r--r--output/outelf.c5
18 files changed, 238 insertions, 219 deletions
diff --git a/.gitignore b/.gitignore
index 82ec14ea..7afbbe25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,7 @@ TAGS
/asm/pptok.ph
/asm/tokens.h
/asm/tokhash.c
+/asm/warnings.c
/config/config.h
/config/config.h.in
/config.log
@@ -66,6 +67,8 @@ TAGS
/doc/info
/doc/inslist.src
/doc/version.src
+/doc/warnings.src
+/include/warnings.h
/macros/macros.c
/misc/omfdump
/nasm
diff --git a/Makefile.in b/Makefile.in
index 78eaffe2..d2f5889f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -114,7 +114,7 @@ LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) x86/regdis.$(O) \
x86/disp8.$(O) x86/iflag.$(O) \
\
- asm/error.$(O) \
+ asm/error.$(O) asm/warnings.$(O) \
asm/float.$(O) \
asm/directiv.$(O) asm/directbl.$(O) \
asm/pragma.$(O) \
@@ -240,6 +240,23 @@ x86/regs.h: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl h \
$(srcdir)/x86/regs.dat > x86/regs.h
+# Extract warnings from source code. Since this depends on
+# ALL the source files, this is only done on demand.
+WARNFILES = asm/warnings.c include/warnings.h doc/warnings.src
+
+warnings:
+ rm -f $(WARNFILES)
+ $(MAKE) $(WARNFILES)
+
+asm/warnings.c: asm/warnings.pl
+ $(RUNPERL) $(srcdir)/asm/warnings.pl c asm/warnings.c $(srcdir)
+
+include/warnings.h: asm/warnings.pl
+ $(RUNPERL) $(srcdir)/asm/warnings.pl h include/warnings.h $(srcdir)
+
+doc/warnings.src: asm/warnings.pl
+ $(RUNPERL) $(srcdir)/asm/warnings.pl doc doc/warnings.src $(srcdir)
+
# Assembler token hash
asm/tokhash.c: x86/insns.dat x86/regs.dat asm/tokens.dat asm/tokhash.pl \
perllib/phash.ph
diff --git a/asm/assemble.c b/asm/assemble.c
index 964efb0e..03335eb3 100644
--- a/asm/assemble.c
+++ b/asm/assemble.c
@@ -405,7 +405,12 @@ static void out(struct out_data *data)
nasm_nonfatal("%u-bit signed relocation unsupported by output format %s",
(unsigned int)(asize << 3), ofmt->shortname);
} else {
- nasm_warnf(WARN_ZEXTRELOC,
+ /*!
+ *!zext-reloc [on] relocation zero-extended to match output format
+ *! warns that a relocation has been zero-extended due
+ *! to limitations in the output format.
+ */
+ nasm_warnf(WARN_ZEXT_RELOC,
"%u-bit %s relocation zero-extended from %u bits",
(unsigned int)(asize << 3),
data->type == OUT_SEGMENT ? "segment" : "unsigned",
@@ -555,6 +560,15 @@ static bool jmp_match(int32_t segment, int64_t offset, int bits,
if (is_byte && c == 0371 && ins->prefixes[PPS_REP] == P_BND) {
/* jmp short (opcode eb) cannot be used with bnd prefix. */
ins->prefixes[PPS_REP] = P_none;
+ /*!
+ *!bnd [on] invalid BND prefixes
+ *! warns about ineffective use of the \c{BND} prefix when the
+ *! \c{JMP} instruction is converted to the \c{SHORT} form.
+ *! This should be extremely rare since the short \c{JMP} only
+ *! is applicable to jumps inside the same module, but if
+ *! it is legitimate, it may be necessary to use
+ *! \c{BND JMP DWORD}...
+ */
nasm_warnf(WARN_BND | ERR_PASS2 ,
"jmp short does not init bnd regs - bnd prefix dropped.");
}
@@ -904,6 +918,11 @@ static void bad_hle_warn(const insn * ins, uint8_t hleok)
if (!is_class(MEMORY, ins->oprs[0].type))
ww = w_inval; /* HLE requires operand 0 to be memory */
+ /*!
+ *!hle [on] invalid HLE prefixes
+ *! warns about invalid use of the HLE \c{XACQUIRE} or \c{XRELEASE}
+ *! prefixes.
+ */
switch (ww) {
case w_none:
break;
@@ -1398,6 +1417,10 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck &&
(!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) {
+ /*!
+ *!lock [on] lock prefix on unlockable instructions
+ *! warns about \c{LOCK} prefixes on unlockable instructions.
+ */
nasm_warnf(WARN_LOCK | ERR_PASS2 , "instruction is not lockable");
}
diff --git a/asm/directiv.c b/asm/directiv.c
index 90b8b7b2..66901530 100644
--- a/asm/directiv.c
+++ b/asm/directiv.c
@@ -435,9 +435,7 @@ bool process_directives(char *directive)
}
case D_WARNING: /* [WARNING {+|-|*}warn-name] */
- if (!set_warning_status(value)) {
- nasm_warnf(WARN_UNK_WARNING, "unknown warning option: %s", value);
- }
+ set_warning_status(value);
break;
case D_CPU: /* [CPU] */
diff --git a/asm/error.c b/asm/error.c
index 2a0b34ad..ea2620fa 100644
--- a/asm/error.c
+++ b/asm/error.c
@@ -42,49 +42,6 @@
#include "nasmlib.h"
#include "error.h"
-/*
- * Description of the suppressible warnings for the command line and
- * the [warning] directive.
- */
-#define on (WARN_ST_ENABLED)
-#define off 0
-#define err (WARN_ST_ENABLED|WARN_ST_ERROR)
-
-const struct warning warnings[WARN_ALL+1] = {
- {NULL, NULL, on}, /* must be on - used for unconditional enable */
- {"macro-params", "macro calls with wrong parameter count", on},
- {"macro-selfref", "cyclic macro references", off},
- {"macro-defaults", "macros with more default than optional parameters", on},
- {"orphan-labels", "labels alone on lines without trailing `:'", on},
- {"number-overflow", "numeric constant does not fit", on},
- {"gnu-elf-extensions", "using 8- or 16-bit relocation in ELF32, a GNU extension", off},
- {"float-overflow", "floating point overflow", on},
- {"float-denorm", "floating point denormal", off},
- {"float-underflow", "floating point underflow", off},
- {"float-toolong", "too many digits in floating-point number", on},
- {"user", "%warning directives", on},
- {"lock", "lock prefix on unlockable instructions", on},
- {"hle", "invalid hle prefixes", on},
- {"bnd", "invalid bnd prefixes", on},
- {"zext-reloc", "relocation zero-extended to match output format", on},
- {"ptr", "non-NASM keyword used in other assemblers", on},
- {"bad-pragma", "empty or malformed %pragma", off},
- {"unknown-pragma", "unknown %pragma facility or directive", off},
- {"not-my-pragma", "%pragma not applicable to this compilation", off},
- {"unknown-warning", "unknown warning in -W/-w or warning directive", off},
- {"negative-rep", "regative %rep count", on},
- {"phase", "phase error during stabilization", off},
- {"label-redef", "label redefined to an identical value", off},
- {"label-redef-late", "label (re)defined during code generation", err},
-
- /* THESE ENTRIES SHOULD COME LAST */
- {"other", "any warning not specifially mentioned above", on},
- {"all", "all possible warnings", off}
-};
-
-uint8_t warning_state[WARN_ALL];/* Current state */
-uint8_t warning_state_init[WARN_ALL]; /* Command-line state, for reset */
-
/* Global error handling function */
vefunc nasm_verror;
@@ -134,11 +91,22 @@ fatal_func nasm_assert_failed(const char *file, int line, const char *msg)
/*
* This is called when processing a -w or -W option, or a warning directive.
* Returns on if if the action was successful.
+ *
+ * Special pseudo-warnings:
+ *
+ *!other [on] any warning not specifially mentioned above
+ *! specifies any warning not included in any specific warning class.
+ *
+ *!all [all] all possible warnings
+ *! is an alias for \e{all} suppressible warning classes.
+ *! Thus, \c{-w+all} enables all available warnings, and \c{-w-all}
+ *! disables warnings entirely (since NASM 2.13).
*/
bool set_warning_status(const char *value)
{
enum warn_action { WID_OFF, WID_ON, WID_RESET };
enum warn_action action;
+ const char *name;
bool ok = false;
uint8_t mask;
int i;
@@ -192,12 +160,13 @@ bool set_warning_status(const char *value)
}
}
+ name = value ? value : "<none>";
if (value && !nasm_stricmp(value, "all"))
value = NULL;
/* This is inefficient, but it shouldn't matter... */
- for (i = 0; i < WARN_ALL; i++) {
- if (!value || !nasm_stricmp(value, warnings[i].name)) {
+ for (i = 1; i < WARN_IDX_ALL; i++) {
+ if (!value || !nasm_stricmp(value, warning_name[i])) {
ok = true; /* At least one action taken */
switch (action) {
case WID_OFF:
@@ -214,5 +183,14 @@ bool set_warning_status(const char *value)
}
}
+ if (!ok) {
+ /*!
+ *!unknown-warning [off] unknown warning in -W/-w or warning directive
+ *! warns about a \c{-w} or \c{-W} option or a \c{[WARNING]} directive
+ *! that contains an unknown warning name or is otherwise not possible to process.
+ */
+ nasm_warnf(WARN_UNKNOWN_WARNING, "unknown warning name: %s", name);
+ }
+
return ok;
}
diff --git a/asm/float.c b/asm/float.c
index 6f26e678..54af63cb 100644
--- a/asm/float.c
+++ b/asm/float.c
@@ -232,6 +232,10 @@ static bool ieee_flconvert(const char *string, fp_limb *mant,
*p++ = *string - '0';
} else {
if (!warned) {
+ /*!
+ *!float-toolong [on] too many digits in floating-point number
+ *! warns about too many digits in floating-point numbers.
+ */
nasm_warnf(WARN_FLOAT_TOOLONG|ERR_PASS2,
"floating-point constant significand contains "
"more than %i digits", MANT_DIGITS);
@@ -798,9 +802,8 @@ static int to_float(const char *str, int s, uint8_t *result,
if (exponent >= 2 - expmax && exponent <= expmax) {
type = FL_NORMAL;
} else if (exponent > 0) {
- if (pass0 == 1)
- nasm_warnf(WARN_FLOAT_OVERFLOW|ERR_PASS2,
- "overflow in floating-point constant");
+ nasm_warnf(WARN_FLOAT_OVERFLOW|ERR_PASS2,
+ "overflow in floating-point constant");
type = FL_INFINITY;
} else {
/* underflow or denormal; the denormal code handles
@@ -833,13 +836,22 @@ static int to_float(const char *str, int s, uint8_t *result,
mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
} else {
if (daz || is_zero(mant)) {
- /* Flush denormals to zero */
+ /*!
+ *!float-underflow [off] floating point underflow
+ *! warns about floating point underflow (a nonzero
+ *! constant rounded to zero.)
+ */
nasm_warnf(WARN_FLOAT_UNDERFLOW|ERR_PASS2,
"underflow in floating-point constant");
goto zero;
- } else
+ } else {
+ /*!
+ *!float-denorm [off] floating point denormal
+ *! warns about denormal floating point constants.
+ */
nasm_warnf(WARN_FLOAT_DENORM|ERR_PASS2,
"denormal floating-point constant");
+ }
}
break;
}
@@ -853,8 +865,12 @@ static int to_float(const char *str, int s, uint8_t *result,
ieee_shr(mant, 1);
exponent++;
if (exponent >= (expmax << 1)-1) {
- nasm_warnf(WARN_FLOAT_OVERFLOW|ERR_PASS2,
- "overflow in floating-point constant");
+ /*!
+ *!float-overflow [on] floating point overflow
+ *! warns about floating point underflow.
+ */
+ nasm_warnf(WARN_FLOAT_OVERFLOW|ERR_PASS2,
+ "overflow in floating-point constant");
type = FL_INFINITY;
goto overflow;
}
diff --git a/asm/labels.c b/asm/labels.c
index ead1f34b..7d87503d 100644
--- a/asm/labels.c
+++ b/asm/labels.c
@@ -505,6 +505,12 @@ void define_label(const char *label, int32_t segment,
nasm_nonfatal("label `%s' inconsistently redefined", lptr->defn.label);
noteflags = ERR_NOTE|ERR_HERE;
} else {
+ /*!
+ *!label-redef [off] label redefined to an identical value
+ *! warns if a label is defined more than once, but the
+ *! value is identical. It is an unconditional error to
+ *! define the same label more than once to \e{different} values.
+ */
nasm_warnf(WARN_LABEL_REDEF|ERR_PASS2,
"label `%s' redefined to an identical value", lptr->defn.label);
noteflags = ERR_NOTE|ERR_HERE|WARN_LABEL_REDEF|ERR_PASS2;
@@ -516,13 +522,16 @@ void define_label(const char *label, int32_t segment,
lptr->defn.label);
src_set(saved_line, saved_fname);
} else if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) {
- /*
- * WARN_LABEL_REDEF_LATE defaults to an error, as this should never actually happen.
- * Just in case this is a backwards compatibility problem, still make it a
- * warning so that the user can suppress or demote it.
+ /*!
+ *!label-redef-late [err] label (re)defined during code generation
+ *! the value of a label changed during the final, code-generation
+ *! pass. This may be the result of strange use of the
+ *! preprocessor. This is very likely to produce incorrect code and
+ *! may end up being an unconditional error in a future
+ *! version of NASM.
*
- * As a special case, LBL_SPECIAL symbols are allowed to be changed
- * even during the last pass.
+ * Note: As a special case, LBL_SPECIAL symbols are allowed
+ * to be changed even during the last pass.
*/
nasm_warnf(WARN_LABEL_REDEF_LATE,
"label `%s' %s during code generation",
diff --git a/asm/nasm.c b/asm/nasm.c
index 2a95f6a1..6bc55528 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -510,7 +510,7 @@ int main(int argc, char **argv)
}
/* Save away the default state of warnings */
- memcpy(warning_state_init, warning_state, sizeof warning_state);
+ memcpy(warning_state_init, warning_state, sizeof warning_state_init);
/* Dependency filename if we are also doing other things */
if (!depend_file && (operating_mode & ~OP_DEPEND)) {
@@ -1040,11 +1040,8 @@ static bool process_arg(char *p, char *q, int pass)
case 'w':
case 'W':
- if (pass == 2) {
- if (!set_warning_status(param)) {
- nasm_warnf(WARN_UNK_WARNING, "unknown warning option: %s", param);
- }
- }
+ if (pass == 2)
+ set_warning_status(param);
break;
case 'M':
@@ -1323,14 +1320,13 @@ static void parse_cmdline(int argc, char **argv, int pass)
{
FILE *rfile;
char *envreal, *envcopy = NULL, *p;
- int i;
/*
* Initialize all the warnings to their default state, including
* warning index 0 used for "always on".
*/
- for (i = 0; i < WARN_ALL; i++)
- warning_state_init[i] = warning_state[i] = warnings[i].state;
+ memcpy(warning_state, warning_default, sizeof warning_state);
+ memcpy(warning_state_init, warning_default, sizeof warning_state_init);
/*
* First, process the NASMENV environment variable.
@@ -1640,7 +1636,14 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
if (global_offset_changed && !terminate_after_phase) {
switch (pass0) {
case 1:
- nasm_warnf(WARN_PHASE, "phase error during stabilization pass, hoping for the best");
+ /*!
+ *!phase [off] phase error during stabilization
+ *! warns about symbols having changed values during
+ *! the second-to-last assembly pass. This is not
+ *! inherently fatal, but may be a source of bugs.
+ */
+ nasm_warnf(WARN_PHASE, "phase error during stabilization "
+ "pass, hoping for the best");
break;
case 2:
@@ -1712,7 +1715,7 @@ static size_t warn_index(errflags severity)
severity |= WARN_OTHER;
index = WARN_IDX(severity);
- nasm_assert(index < WARN_ALL);
+ nasm_assert(index < WARN_IDX_ALL);
return index;
}
@@ -1830,8 +1833,8 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
*warnsuf = 0;
if (spec_type == ERR_WARNING) {
snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
- true_type ? "error=" : "",
- warnings[warn_index(severity)].name);
+ (true_type >= ERR_NONFATAL) ? "error=" : "",
+ warning_name[warn_index(severity)]);
}
*linestr = 0;
@@ -1989,14 +1992,15 @@ static void help(const char xopt)
}
}
- printf("\nWarnings for the -W/-w options: (default in brackets)\n");
+ printf("\nWarnings for the -W/-w options: (defaults in brackets)\n");
- for (i = 1; i <= WARN_ALL; i++)
+ for (i = 1; i <= WARN_IDX_ALL; i++) {
printf(" %-23s %s%s\n",
- warnings[i].name, warnings[i].help,
- i == WARN_ALL ? "\n" :
- (warnings[i].state & WARN_ST_ERROR) ? " [error]" :
- (warnings[i].state & WARN_ST_ENABLED) ? " [on]" : " [off]");
+ warning_name[i], warning_help[i],
+ i == WARN_IDX_ALL ? "\n" :
+ (warning_default[i] & WARN_ST_ERROR) ? " [error]" :
+ (warning_default[i] & WARN_ST_ENABLED) ? " [on]" : " [off]");
+ }
if (xopt == 'f') {
printf("valid output formats for -f are"
diff --git a/asm/parser.c b/asm/parser.c
index 04def6b4..c34f8337 100644
--- a/asm/parser.c
+++ b/asm/parser.c
@@ -463,6 +463,12 @@ restart_parse:
if (i == ':') { /* skip over the optional colon */
i = stdscan(NULL, &tokval);
} else if (i == 0) {
+ /*!
+ *!orphan-labels [on] labels alone on lines without trailing `:'
+ *! warns about source lines which contain no instruction but define
+ *! a label without a trailing colon. This is most likely indicative
+ *! of a typo, but is technically correct NASM syntax (see \k{syntax}.)
+ */
nasm_warnf(WARN_ORPHAN_LABELS | ERR_PASS1,
"label alone on a line without a colon might be in error");
}
diff --git a/asm/pragma.c b/asm/pragma.c
index 85e8c9cd..b6878e9d 100644
--- a/asm/pragma.c
+++ b/asm/pragma.c
@@ -146,10 +146,20 @@ found_it:
case DIRR_UNKNOWN:
switch (pragma->opcode) {
case D_none:
+ /*!
+ *!bad-pragma [off] empty or malformed %pragma
+ *! warns about a malformed or otherwise unparsable
+ *! \c{%pragma} directive.
+ */
nasm_error(ERR_WARNING|ERR_PASS2|WARN_BAD_PRAGMA,
"empty %%pragma %s", pragma->facility_name);
break;
default:
+ /*!
+ *!unknown-pragma [off] unknown %pragma facility or directive
+ *! warns about an unknown \c{%pragma} directive.
+ *! This is not yet implemented for most cases.
+ */
nasm_error(ERR_WARNING|ERR_PASS2|WARN_UNKNOWN_PRAGMA,
"unknown %%pragma %s %s",
pragma->facility_name, pragma->opname);
@@ -176,6 +186,13 @@ found_it:
return true;
}
+/* This warning message is intended for future use */
+/*!
+ *!not-my-pragma [off] %pragma not applicable to this compilation
+ *! warns about a \c{%pragma} directive which is not applicable to
+ *! this particular assembly session. This is not yet implemented.
+ */
+
void process_pragma(char *str)
{
struct pragma pragma;
diff --git a/asm/preproc.c b/asm/preproc.c
index 741430f2..cdea9206 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -2132,8 +2132,15 @@ static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
def->expansion = NULL;
if (def->defaults && def->ndefs > def->nparam_max - def->nparam_min &&
- !def->plus)
- nasm_warnf(ERR_PASS1|WARN_MACRO_DEFAULTS, "too many default macro parameters in macro `%s'", def->name);
+ !def->plus) {
+ /*
+ *!macro-defaults [on] macros with more default than optional parameters
+ *! warns when a macro has more default parameters than optional parameters.
+ *! See \k{mlmacdef} for why might want to disable this warning.
+ */
+ nasm_warnf(ERR_PASS1|WARN_MACRO_DEFAULTS,
+ "too many default macro parameters in macro `%s'", def->name);
+ }
return true;
}
@@ -2655,6 +2662,10 @@ static int do_directive(Token *tline, char **output)
severity = ERR_NONFATAL;
goto issue_error;
case PP_WARNING:
+ /*!
+ *!user [on] %warning directives
+ *! controls output of \c{%warning} directives (see \k{pperror}).
+ */
severity = ERR_WARNING|WARN_USER;
goto issue_error;
@@ -2966,6 +2977,11 @@ issue_error:
count, nasm_limit[LIMIT_REP]);
count = 0;
} else if (count < 0) {
+ /*!
+ *!negative-rep [on] regative %rep count
+ *! warns about negative counts given to the \c{%rep}
+ *! preprocessor directive.
+ */
nasm_warnf(ERR_PASS2|WARN_NEGATIVE_REP,
"negative `%%rep' count: %"PRId64, count);
count = 0;
@@ -4284,11 +4300,18 @@ again:
mstrcmp(m->name, mname,
m->casesense)))
m = m->next;
- if (!m)
+ if (!m) {
+ /*!
+ *!macro-params [on] macro calls with wrong parameter count
+ *! covers warnings about \i{multi-line macros} being invoked
+ *! with the wrong number of parameters. See \k{mlmacover} for an
+ *! example of why you might want to disable this warning.
+ */
nasm_warnf(ERR_PASS1|WARN_MACRO_PARAMS,
"macro `%s' exists, "
"but not taking %d parameters",
mstart->text, nparam);
+ }
}
}
if (m && m->in_progress)
diff --git a/asm/stdscan.c b/asm/stdscan.c
index b197b27f..ee6d0442 100644
--- a/asm/stdscan.c
+++ b/asm/stdscan.c
@@ -167,6 +167,12 @@ int stdscan(void *private_data, struct tokenval *tv)
token_type = nasm_token_hash(ourcopy, tv);
if (unlikely(tv->t_flag & TFLAG_WARN)) {
+ /*!
+ *!ptr [on] non-NASM keyword used in other assemblers
+ *! warns about keywords used in other assemblers that might
+ *! indicate a mistake in the source code. Currently only the MASM
+ *! \c{PTR} keyword is recognized.
+ */
nasm_warnf(ERR_PASS1|WARN_PTR, "`%s' is not a NASM keyword",
tv->t_charptr);
}
diff --git a/asm/warnings.pl b/asm/warnings.pl
index 384c18da..cb336ada 100755
--- a/asm/warnings.pl
+++ b/asm/warnings.pl
@@ -18,7 +18,7 @@ sub quote_for_c($) {
sub find_warnings {
my $infile = $_;
- return unless ($infile =~ /\.[ch]$/i);
+ return unless (basename($infile) =~ /^\w.*\.[ch]$/i);
open(my $in, '<', $infile)
or die "$0: cannot open input file $infile: $!\n";
@@ -50,8 +50,10 @@ sub find_warnings {
my $ws = $1;
my $str = $2;
+ next if ($str eq '');
+
if (!defined($this) || ($ws eq '' && $str ne '')) {
- if ($str =~ /^(\w+)\s+(\w+)\s(.+)$/) {
+ if ($str =~ /^([\w-]+)\s+\[(\w+)\]\s(.+)$/) {
my $name = $1;
my $def = $2;
my $help = $3;
@@ -106,7 +108,7 @@ open(my $out, '>', $outfile)
if ($what eq 'c') {
print $out "#include \"error.h\"\n\n";
- printf $out "const char * const warning_names[%d] = {\n",
+ printf $out "const char * const warning_name[%d] = {\n",
$#warnings + 2;
print $out "\tNULL";
foreach my $warn (@warnings) {
@@ -121,44 +123,58 @@ if ($what eq 'c') {
print $out ",\n\t\"", $help, "\"";
}
print $out "\n};\n\n";
- printf $out "const uint8_t warning_defaults[%d] = {\n",
+ printf $out "const uint8_t warning_default[%d] = {\n",
$#warn_noall + 2;
print $out "\tWARN_INIT_ON"; # for entry 0
foreach my $warn (@warn_noall) {
print $out ",\n\tWARN_INIT_", uc($warn->{def});
}
- print $out "\n};\n";
+ print $out "\n};\n\n";
+ printf $out "uint8_t warning_state[%d];\t/* Current state */\n",
+ $#warn_noall + 2;
+ printf $out "uint8_t warning_state_init[%d];\t/* Command-line state, for reset */\n",
+ $#warn_noall + 2;
} elsif ($what eq 'h') {
- my $guard = basename($outfile);
+ my $filename = basename($outfile);
+ my $guard = $filename;
$guard =~ s/[^A-Za-z0-9_]+/_/g;
$guard = "NASM_\U$guard";
print $out "#ifndef $guard\n";
print $out "#define $guard\n";
print $out "\n";
- print $out "#include \"compiler.h\"\n\n";
+ print $out "#ifndef WARN_SHR\n";
+ print $out "# error \"$filename should only be included from within error.h\"\n";
+ print $out "#endif\n\n";
print $out "enum warn_index {\n";
- printf $out "\tWARN_IDX_%-15s = %2d", 'NONE', 0;
+ printf $out "\tWARN_IDX_%-23s = %3d, /* not suppressible */\n", 'NONE', 0;
my $n = 1;
foreach my $warn (@warnings) {
- printf $out ",\n\tWARN_IDX_%-15s = %2d%s /* %s */",
- $warn->{cname}, $n++, $warn->{help};
+ printf $out "\tWARN_IDX_%-23s = %3d%s /* %s */\n",
+ $warn->{cname}, $n,
+ ($n == $#warnings + 1) ? " " : ",",
+ $warn->{help};
+ $n++;
}
- print $out "\n};\n\n";
+ print $out "};\n\n";
print $out "enum warn_const {\n";
- printf $out "\tWARN_%-19s = %2d << WARN_SHR", 'NONE', 0;
+ printf $out "\tWARN_%-27s = %3d << WARN_SHR", 'NONE', 0;
my $n = 1;
foreach my $warn (@warn_noall) {
- printf $out ",\n\tWARN_%-19s = %2d << WARN_SHR", $warn->{cname}, $n++;
+ printf $out ",\n\tWARN_%-27s = %3d << WARN_SHR", $warn->{cname}, $n++;
}
print $out "\n};\n\n";
- printf $out "extern const char * const warning_names[%d];\n",
+ printf $out "extern const char * const warning_name[%d];\n",
$#warnings + 2;
printf $out "extern const char * const warning_help[%d];\n",
$#warnings + 2;
- printf $out "extern const uint8_t warning_defaults[%d];\n",
+ printf $out "extern const uint8_t warning_default[%d];\n",
+ $#warn_noall + 2;
+ printf $out "extern uint8_t warning_state[%d];\n",
+ $#warn_noall + 2;
+ printf $out "extern uint8_t warning_state_init[%d];\n",
$#warn_noall + 2;
print $out "\n#endif /* $guard */\n";
} elsif ($what eq 'doc') {
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 27e6fadb..efe5fccb 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -31,7 +31,7 @@ CP_UF = cp -ufv
# Auxiliary files referenced by the HTML files
HTMLAUX = nasmdoc.css local.css nasmlogw.png
-SRCS = nasmdoc.src inslist.src changes.src version.src
+SRCS = nasmdoc.src inslist.src changes.src warnings.src version.src
OUT = html nasmdoc.txt nasmdoc.pdf
.SUFFIXES:
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index f1abc507..7c7a75aa 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -809,82 +809,7 @@ disable it by \c{-w-orphan-labels}.
The current \i{warning classes} are:
-\b \i\c{other} specifies any warning not otherwise specified in any
-class. Enabled by default.
-
-\b \i\c{macro-params} covers warnings about \i{multi-line macros}
-being invoked with the wrong number of parameters. Enabled by default;
-see \k{mlmacover} for an example of why you might want to disable it.
-
-\b \i\c{macro-selfref} warns if a macro references itself. Disabled by
-default.
-
-\b \i\c{macro-defaults} warns when a macro has more default parameters
-than optional parameters. Enabled by default; see \k{mlmacdef} for why
-you might want to disable it.
-
-\b \i\c{orphan-labels} covers warnings about source lines which
-contain no instruction but define a label without a trailing colon.
-NASM warns about this somewhat obscure condition by default;
-see \k{syntax} for more information.
-
-\b \i\c{number-overflow} covers warnings about numeric constants which
-don't fit in 64 bits. Enabled by default.
-
-\b \i\c{gnu-elf-extensions} warns if 8-bit or 16-bit relocations
-are used in \c{-f elf} format. The GNU extensions allow this.
-Disabled by default.
-
-\b \i\c{float-overflow} warns about floating point overflow.
-Enabled by default.
-
-\b \i\c{float-denorm} warns about floating point denormals.
-Disabled by default.
-
-\b \i\c{float-underflow} warns about floating point underflow.
-Disabled by default.
-
-\b \i\c{float-toolong} warns about too many digits in floating-point numbers.
-Enabled by default.
-
-\b \i\c{user} controls \c{%warning} directives (see \k{pperror}).
-Enabled by default.
-
-\b \i\c{lock} warns about \c{LOCK} prefixes on unlockable instructions.
-Enabled by default.
-
-\b \i\c{hle} warns about invalid use of the HLE \c{XACQUIRE} or \c{XRELEASE}
-prefixes.
-Enabled by default.
-
-\b \i\c{bnd} warns about ineffective use of the \c{BND} prefix when a relaxed
-form of jmp instruction becomes jmp short form.
-Enabled by default.
-
-\b \i\c{zext-reloc} warns that a relocation has been zero-extended due
-to limitations in the output format. Enabled by default.
-
-\b \i\c\{ptr} warns about keywords used in other assemblers that might
-indicate a mistake in the source code. Currently only the MASM
-\c{PTR} keyword is recognized. Enabled by default.
-
-\b \i\c{bad-pragma} warns about a malformed or otherwise unparsable
-\c{%pragma} directive. Disabled by default.
-
-\b \i\c{unknown-pragma} warns about an unknown \c{%pragma} directive.
-This is not yet implemented. Disabled by default.
-
-\b \i\c{not-my-pragma} warns about a \c{%pragma} directive which is
-not applicable to this particular assembly session. This is not yet
-implemented. Disabled by default.
-
-\b \i\c{unknown-warning} warns about a \c{-w} or \c{-W} option or a
-\c{[WARNING]} directive that contains an unknown warning name or is
-otherwise not possible to process. Disabled by default.
-
-\b \i\c{all} is an alias for \e{all} suppressible warning classes.
-Thus, \c{-w+all} enables all available warnings, and \c{-w-all}
-disables warnings entirely (since NASM 2.13).
+\& warnings.src
Since version 2.00, NASM has also supported the \c{gcc}-like syntax
\c{-Wwarning-class} and \c{-Wno-warning-class} instead of
diff --git a/include/error.h b/include/error.h
index 34e7d50f..3019615b 100644
--- a/include/error.h
+++ b/include/error.h
@@ -83,7 +83,6 @@ static inline vefunc nasm_set_verror(vefunc ve)
* These are the error severity codes which get passed as the first
* argument to an efunc.
*/
-
#define ERR_DEBUG 0x00000000 /* put out debugging message */
#define ERR_NOTE 0x00000001 /* additional error information */
#define ERR_WARNING 0x00000002 /* warn only: no further action */
@@ -107,55 +106,23 @@ static inline vefunc nasm_set_verror(vefunc ve)
* They are assumed to occupy the most significant bits of the
* severity code.
*/
-
#define WARN_SHR 12 /* how far to shift right */
-#define WARN(x) (((errflags)(x)) << WARN_SHR)
-#define WARN_MASK WARN(~0)
#define WARN_IDX(x) (((errflags)(x)) >> WARN_SHR)
-
-#define WARN_MACRO_PARAMS WARN( 1) /* macro-num-parameters warning */
-#define WARN_MACRO_SELFREF WARN( 2) /* macro self-reference */
-#define WARN_MACRO_DEFAULTS WARN( 3) /* macro default parameters check */
-#define WARN_ORPHAN_LABELS WARN( 4) /* orphan label (no colon, and alone on line) */
-#define WARN_NUMBER_OVERFLOW WARN( 5) /* numeric overflow */
-#define WARN_GNU_ELF_EXTENSIONS WARN( 6) /* using GNU ELF extensions */
-#define WARN_FLOAT_OVERFLOW WARN( 7) /* FP overflow */
-#define WARN_FLOAT_DENORM WARN( 8) /* FP denormal */
-#define WARN_FLOAT_UNDERFLOW WARN( 9) /* FP underflow */
-#define WARN_FLOAT_TOOLONG WARN(10) /* FP too many digits */
-#define WARN_USER WARN(11) /* %warning directives */
-#define WARN_LOCK WARN(12) /* bad LOCK prefixes */
-#define WARN_HLE WARN(13) /* bad HLE prefixes */
-#define WARN_BND WARN(14) /* bad BND prefixes */
-#define WARN_ZEXTRELOC WARN(15) /* relocation zero-extended */
-#define WARN_PTR WARN(16) /* not a NASM keyword */
-#define WARN_BAD_PRAGMA WARN(17) /* malformed pragma */
-#define WARN_UNKNOWN_PRAGMA WARN(18) /* unknown pragma */
-#define WARN_NOT_MY_PRAGMA WARN(19) /* pragma inapplicable */
-#define WARN_UNK_WARNING WARN(20) /* unknown warning */
-#define WARN_NEGATIVE_REP WARN(21) /* negative repeat count */
-#define WARN_PHASE WARN(22) /* phase error in pass 1 */
-#define WARN_LABEL_REDEF WARN(23) /* label redefined, but consistent */
-#define WARN_LABEL_REDEF_LATE WARN(24) /* label (re)defined during code generation */
-
-/* These two should come last */
-#define WARN_ALL (24+2) /* Do not use WARN() here */
-#define WARN_OTHER WARN(WARN_ALL-1) /* any noncategorized warning */
+#define WARN_MASK ((~(errflags)0) << WARN_SHR)
/* This is a bitmask */
#define WARN_ST_ENABLED 1 /* Warning is currently enabled */
#define WARN_ST_ERROR 2 /* Treat this warning as an error */
-struct warning {
- const char *name;
- const char *help;
- uint8_t state; /* Default state for this warning */
-};
-extern const struct warning warnings[WARN_ALL+1];
-extern uint8_t warning_state[WARN_ALL];
-extern uint8_t warning_state_init[WARN_ALL];
+/* Possible initial state for warnings */
+#define WARN_INIT_OFF 0
+#define WARN_INIT_ON WARN_ST_ENABLED
+#define WARN_INIT_ERR (WARN_ST_ENABLED|WARN_ST_ERROR)
/* Process a warning option or directive */
bool set_warning_status(const char *value);
+/* Should be included from within error.h only */
+#include "warnings.h"
+
#endif /* NASM_ERROR_H */
diff --git a/nasmlib/readnum.c b/nasmlib/readnum.c
index 02e30830..4e73c1a1 100644
--- a/nasmlib/readnum.c
+++ b/nasmlib/readnum.c
@@ -163,10 +163,16 @@ int64_t readnum(const char *str, bool *error)
r++;
}
- if (warn)
+ if (warn) {
+ /*!
+ *!number-overflow [on] numeric constant does not fit
+ *! covers warnings about numeric constants which
+ *! don't fit in 64 bits.
+ */
nasm_error(ERR_WARNING | ERR_PASS1 | WARN_NUMBER_OVERFLOW,
"numeric constant %s does not fit in 64 bits",
str);
+ }
return result * sign;
}
diff --git a/output/outelf.c b/output/outelf.c
index 8270ba0b..2adf4692 100644
--- a/output/outelf.c
+++ b/output/outelf.c
@@ -919,6 +919,11 @@ static void elf32_out(int32_t segto, const void *data,
}
if (gnu16) {
+ /*!
+ *!gnu-elf-extensions [off] using 8- or 16-bit relocation in ELF32, a GNU extension
+ *! warns if 8-bit or 16-bit relocations are used in the \c{elf32} output format.
+ *! The GNU extensions allow this.
+ */
nasm_warnf(WARN_GNU_ELF_EXTENSIONS, "8- or 16-bit relocations "
"in ELF32 is a GNU extension");
} else if (asize != 4 && segment != NO_SEG) {