mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-27 08:10:07 +08:00
warnings: define warning classes at point of use
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>
This commit is contained in:
parent
6bde2ed880
commit
723ab481a6
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||
|
19
Makefile.in
19
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
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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] */
|
||||
|
68
asm/error.c
68
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;
|
||||
}
|
||||
|
30
asm/float.c
30
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;
|
||||
}
|
||||
|
21
asm/labels.c
21
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",
|
||||
|
42
asm/nasm.c
42
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"
|
||||
|
@ -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");
|
||||
}
|
||||
|
17
asm/pragma.c
17
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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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') {
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user