Add macro-defaults warning class and documentation.
This commit is contained in:
parent
932de6c252
commit
22343c2c72
5 changed files with 131 additions and 32 deletions
|
@ -852,29 +852,46 @@ disable it by \c{-w-orphan-labels}.
|
||||||
|
|
||||||
The \i{suppressible warning} classes are:
|
The \i{suppressible warning} classes are:
|
||||||
|
|
||||||
|
\b \i\c{error} decides if warnings should be treated as errors.
|
||||||
|
It is disabled by default.
|
||||||
|
|
||||||
\b \i\c{macro-params} covers warnings about \i{multi-line macros}
|
\b \i\c{macro-params} covers warnings about \i{multi-line macros}
|
||||||
being invoked with the wrong number of parameters. This warning
|
being invoked with the wrong number of parameters. This warning
|
||||||
class is enabled by default; see \k{mlmacover} for an example of why
|
class is enabled by default; see \k{mlmacover} for an example of why
|
||||||
you might want to disable it.
|
you might want to disable it.
|
||||||
|
|
||||||
\b \i\c{macro-selfref} warns if a macro references itself. This
|
\b \i\c{macro-selfref} warns if a macro references itself. This
|
||||||
warning class is enabled by default.
|
warning class is disabled by default.
|
||||||
|
|
||||||
|
\b\i\c{macro-defaults} warns when a macro has more default
|
||||||
|
parameters than optional parameters. This warning class
|
||||||
|
is 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
|
\b \i\c{orphan-labels} covers warnings about source lines which
|
||||||
contain no instruction but define a label without a trailing colon.
|
contain no instruction but define a label without a trailing colon.
|
||||||
NASM does not warn about this somewhat obscure condition by default;
|
NASM warns about this somewhat obscure condition by default;
|
||||||
see \k{syntax} for an example of why you might want it to.
|
see \k{syntax} for more information.
|
||||||
|
|
||||||
\b \i\c{number-overflow} covers warnings about numeric constants which
|
\b \i\c{number-overflow} covers warnings about numeric constants which
|
||||||
don't fit in 32 bits (for example, it's easy to type one too many Fs
|
don't fit in 64 bits. This warning class is enabled by default.
|
||||||
and produce \c{0x7ffffffff} by mistake). This warning class is
|
|
||||||
enabled by default.
|
|
||||||
|
|
||||||
\b \i\c{gnu-elf-extensions} warns if 8-bit or 16-bit relocations
|
\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.
|
are used in \c{-f elf} format. The GNU extensions allow this.
|
||||||
This warning class is enabled by default.
|
This warning class is disabled by default.
|
||||||
|
|
||||||
\b In addition, you can set warning classes across sections.
|
\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.
|
||||||
|
|
||||||
|
In addition, you can set warning classes across sections.
|
||||||
Warning classes may be enabled with \i\c{[warning +warning-name]},
|
Warning classes may be enabled with \i\c{[warning +warning-name]},
|
||||||
disabled with \i\c{[warning -warning-name]} or reset to their
|
disabled with \i\c{[warning -warning-name]} or reset to their
|
||||||
original value with \i\c{[warning *warning-name]}. No "user form"
|
original value with \i\c{[warning *warning-name]}. No "user form"
|
||||||
|
@ -2480,6 +2497,19 @@ then it could be called with between one and three parameters, and
|
||||||
specified by the macro call, would default to \c{eax}, and \c{%3} if
|
specified by the macro call, would default to \c{eax}, and \c{%3} if
|
||||||
not specified would default to \c{[ebx+2]}.
|
not specified would default to \c{[ebx+2]}.
|
||||||
|
|
||||||
|
You can provide extra information to a macro by providing
|
||||||
|
too many default parameters:
|
||||||
|
|
||||||
|
\c %macro quux 1 something
|
||||||
|
|
||||||
|
This will trigger a warning by default; see \k{opt-w} for
|
||||||
|
more information.
|
||||||
|
When \c{quux} is invoked, it receives not one but two parameters.
|
||||||
|
\c{something} can be referred to as \c{%2}. The difference
|
||||||
|
between passing \c{something} this way and writing \c{something}
|
||||||
|
in the macro body is that with this way \c{something} is evaluated
|
||||||
|
when the macro is defined, not when it is expanded.
|
||||||
|
|
||||||
You may omit parameter defaults from the macro definition, in which
|
You may omit parameter defaults from the macro definition, in which
|
||||||
case the parameter default is taken to be blank. This can be useful
|
case the parameter default is taken to be blank. This can be useful
|
||||||
for macros which can take a variable number of parameters, since the
|
for macros which can take a variable number of parameters, since the
|
||||||
|
@ -2499,11 +2529,12 @@ default parameters. Examples of this usage are shown in \k{rotate}.
|
||||||
|
|
||||||
\S{percent0} \i\c{%0}: \I{counting macro parameters}Macro Parameter Counter
|
\S{percent0} \i\c{%0}: \I{counting macro parameters}Macro Parameter Counter
|
||||||
|
|
||||||
For a macro which can take a variable number of parameters, the
|
The parameter reference \c{%0} will return a numeric constant giving the
|
||||||
parameter reference \c{%0} will return a numeric constant giving the
|
number of parameters received, that is, if \c{%0} is n then \c{%}n is the
|
||||||
number of parameters passed to the macro. This can be used as an
|
last parameter. \c{%0} is mostly useful for macros that can take a variable
|
||||||
argument to \c{%rep} (see \k{rep}) in order to iterate through all
|
number of parameters. It can be used as an argument to \c{%rep}
|
||||||
the parameters of a macro. Examples are given in \k{rotate}.
|
(see \k{rep}) in order to iterate through all the parameters of a macro.
|
||||||
|
Examples are given in \k{rotate}.
|
||||||
|
|
||||||
|
|
||||||
\S{rotate} \i\c{%rotate}: \i{Rotating Macro Parameters}
|
\S{rotate} \i\c{%rotate}: \i{Rotating Macro Parameters}
|
||||||
|
|
9
nasm.c
9
nasm.c
|
@ -105,16 +105,16 @@ static const char *depend_file = NULL;
|
||||||
static bool suppressed[ERR_WARN_MAX+1];
|
static bool suppressed[ERR_WARN_MAX+1];
|
||||||
|
|
||||||
static bool suppressed_global[ERR_WARN_MAX+1] = {
|
static bool suppressed_global[ERR_WARN_MAX+1] = {
|
||||||
true, false, true, false, false, true, false, true, true, false
|
true, false, true, false, false, false, true, false, true, true, false
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
* The option names for the suppressible warnings. As before, entry
|
* The option names for the suppressible warnings. As before, entry
|
||||||
* zero does nothing.
|
* zero does nothing.
|
||||||
*/
|
*/
|
||||||
static const char *suppressed_names[ERR_WARN_MAX+1] = {
|
static const char *suppressed_names[ERR_WARN_MAX+1] = {
|
||||||
"error", "macro-params", "macro-selfref", "orphan-labels",
|
"error", "macro-params", "macro-selfref", "macro-defaults",
|
||||||
"number-overflow", "gnu-elf-extensions", "float-overflow",
|
"orphan-labels", "number-overflow", "gnu-elf-extensions",
|
||||||
"float-denorm", "float-underflow", "float-toolong"
|
"float-overflow", "float-denorm", "float-underflow", "float-toolong"
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -125,6 +125,7 @@ static const char *suppressed_what[ERR_WARN_MAX+1] = {
|
||||||
"treat warnings as errors",
|
"treat warnings as errors",
|
||||||
"macro calls with wrong parameter count",
|
"macro calls with wrong parameter count",
|
||||||
"cyclic macro references",
|
"cyclic macro references",
|
||||||
|
"macros with more default than optional parameters",
|
||||||
"labels alone on lines without trailing `:'",
|
"labels alone on lines without trailing `:'",
|
||||||
"numeric constants does not fit in 64 bits",
|
"numeric constants does not fit in 64 bits",
|
||||||
"using 8- or 16-bit relocation in ELF32, a GNU extension",
|
"using 8- or 16-bit relocation in ELF32, a GNU extension",
|
||||||
|
|
27
nasmlib.h
27
nasmlib.h
|
@ -71,28 +71,29 @@ extern efunc nasm_malloc_error;
|
||||||
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
|
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
|
||||||
#define ERR_USAGE 0x00000020 /* print a usage message */
|
#define ERR_USAGE 0x00000020 /* print a usage message */
|
||||||
#define ERR_PASS1 0x00000040 /* only print this error on pass one */
|
#define ERR_PASS1 0x00000040 /* only print this error on pass one */
|
||||||
#define ERR_NO_SEVERITY 0x00000080 /* suppress printing severity */
|
#define ERR_NO_SEVERITY 0x00000080 /* suppress printing severity */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These codes define specific types of suppressible warning.
|
* These codes define specific types of suppressible warning.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ERR_WARN_MASK 0x0000FF00 /* the mask for this feature */
|
#define ERR_WARN_MASK 0x0000FF00 /* the mask for this feature */
|
||||||
#define ERR_WARN_SHR 8 /* how far to shift right */
|
#define ERR_WARN_SHR 8 /* how far to shift right */
|
||||||
|
|
||||||
#define WARN(x) ((x) << ERR_WARN_SHR)
|
#define WARN(x) ((x) << ERR_WARN_SHR)
|
||||||
|
|
||||||
#define ERR_WARN_MNP WARN(1) /* macro-num-parameters warning */
|
#define ERR_WARN_MNP WARN( 1) /* macro-num-parameters warning */
|
||||||
#define ERR_WARN_MSR WARN(2) /* macro self-reference */
|
#define ERR_WARN_MSR WARN( 2) /* macro self-reference */
|
||||||
#define ERR_WARN_OL WARN(3) /* orphan label (no colon, and
|
#define ERR_WARN_MDP WARN( 3) /* macro default parameters check */
|
||||||
* alone on line) */
|
#define ERR_WARN_OL WARN( 4) /* orphan label (no colon, and
|
||||||
#define ERR_WARN_NOV WARN(4) /* numeric overflow */
|
* alone on line) */
|
||||||
#define ERR_WARN_GNUELF WARN(5) /* using GNU ELF extensions */
|
#define ERR_WARN_NOV WARN( 5) /* numeric overflow */
|
||||||
#define ERR_WARN_FL_OVERFLOW WARN(6) /* FP overflow */
|
#define ERR_WARN_GNUELF WARN( 6) /* using GNU ELF extensions */
|
||||||
#define ERR_WARN_FL_DENORM WARN(7) /* FP denormal */
|
#define ERR_WARN_FL_OVERFLOW WARN( 7) /* FP overflow */
|
||||||
#define ERR_WARN_FL_UNDERFLOW WARN(8) /* FP underflow */
|
#define ERR_WARN_FL_DENORM WARN( 8) /* FP denormal */
|
||||||
#define ERR_WARN_FL_TOOLONG WARN(9) /* FP too many digits */
|
#define ERR_WARN_FL_UNDERFLOW WARN( 9) /* FP underflow */
|
||||||
#define ERR_WARN_MAX 9 /* the highest numbered one */
|
#define ERR_WARN_FL_TOOLONG WARN(10) /* FP too many digits */
|
||||||
|
#define ERR_WARN_MAX 10 /* the highest numbered one */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrappers around malloc, realloc and free. nasm_malloc will
|
* Wrappers around malloc, realloc and free. nasm_malloc will
|
||||||
|
|
|
@ -1880,8 +1880,10 @@ static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
|
||||||
}
|
}
|
||||||
def->expansion = NULL;
|
def->expansion = NULL;
|
||||||
|
|
||||||
if(def->defaults && def->ndefs > def->nparam_max - def->nparam_min)
|
if(def->defaults &&
|
||||||
error(ERR_WARNING, "too much default macro parameters");
|
def->ndefs > def->nparam_max - def->nparam_min &&
|
||||||
|
!def->plus)
|
||||||
|
error(ERR_WARNING | ERR_WARN_MDP, "too many default macro parameters");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
64
test/macro-defaults.asm
Executable file
64
test/macro-defaults.asm
Executable file
|
@ -0,0 +1,64 @@
|
||||||
|
;Testname=warning; Arguments=-fbin -omacdef.bin -w+macro-defaults; Files=.stdout .stderr macdef.bin
|
||||||
|
;Testname=nonwarning; Arguments=-fbin -omacdef.bin -w-macro-defaults; Files=.stdout .stderr macdef.bin
|
||||||
|
|
||||||
|
%MACRO mmac_fix 1 a
|
||||||
|
; While defined to take one parameter, any invocation will
|
||||||
|
; see two, due to the default parameter.
|
||||||
|
%warning %0 %1 %2 %3 %4 %5
|
||||||
|
%ENDMACRO
|
||||||
|
mmac_fix one
|
||||||
|
|
||||||
|
%MACRO mmac_var 1-2 a,b
|
||||||
|
; While defined to take one or two parameters, invocations
|
||||||
|
; will see three, due to the default parameters.
|
||||||
|
%warning %0 %1 %2 %3 %4 %5
|
||||||
|
%ENDMACRO
|
||||||
|
mmac_var one
|
||||||
|
mmac_var one,two
|
||||||
|
|
||||||
|
%MACRO mmac_plus 1-2+ a,b
|
||||||
|
; This does not warn. Although this looks like two default
|
||||||
|
; parameters, it ends up being only one: the "+" limits it
|
||||||
|
; to two parameters; if invoked without a second parameter
|
||||||
|
; the second parameter will be "a,b".
|
||||||
|
%warning %0 %1 %2 %3 %4 %5
|
||||||
|
;Check rotating behaviour
|
||||||
|
%ENDMACRO
|
||||||
|
mmac_plus one
|
||||||
|
mmac_plus one,two
|
||||||
|
mmac_plus one,two,three
|
||||||
|
|
||||||
|
%MACRO mmac_star 1-* a,b
|
||||||
|
; This does not warn. Because the "*" extends the range of
|
||||||
|
; parameters to infinity, the "a,b" default parameters can
|
||||||
|
; not exceed that range.
|
||||||
|
%warning %0 %1 %2 %3 %4 %5
|
||||||
|
%ENDMACRO
|
||||||
|
mmac_star one
|
||||||
|
mmac_star one,two
|
||||||
|
mmac_star one,two,three
|
||||||
|
|
||||||
|
%MACRO mmac_rotate 0-* a,b
|
||||||
|
%warning %0 %1 %2 %3 %4 %5
|
||||||
|
;%rotate should rotate all parameters
|
||||||
|
%rotate 1
|
||||||
|
%warning %0 %1 %2 %3 %4 %5
|
||||||
|
%ENDMACRO
|
||||||
|
mmac_rotate
|
||||||
|
mmac_rotate one
|
||||||
|
mmac_rotate one,two
|
||||||
|
mmac_rotate one,two,three
|
||||||
|
|
||||||
|
;Scope / evaluation time test
|
||||||
|
%define I 0
|
||||||
|
%assign J 0
|
||||||
|
%xdefine K 0
|
||||||
|
|
||||||
|
%MACRO mmac_scope 0 I J K
|
||||||
|
%warning %1 %2 %3
|
||||||
|
%ENDMACRO
|
||||||
|
|
||||||
|
%define I 1
|
||||||
|
%assign J 1
|
||||||
|
%xdefine K 1
|
||||||
|
mmac_scope
|
Loading…
Reference in a new issue