diff options
-rw-r--r-- | asm/error.c | 73 | ||||
-rw-r--r-- | asm/nasm.c | 4 | ||||
-rw-r--r-- | asm/parser.c | 5 | ||||
-rw-r--r-- | asm/pragma.c | 17 | ||||
-rwxr-xr-x | asm/warnings.pl | 92 | ||||
-rw-r--r-- | nasm.txt | 4 | ||||
-rw-r--r-- | output/outdbg.c | 2 | ||||
-rw-r--r-- | test/br3392538.asm | 2 | ||||
-rw-r--r-- | travis/test/aoutso.stderr | 2 | ||||
-rw-r--r-- | travis/test/elfso-o0.stderr | 2 | ||||
-rw-r--r-- | travis/test/elfso-ox.stderr | 2 | ||||
-rw-r--r-- | travis/test/tmap.o.stderr | 2 |
12 files changed, 144 insertions, 63 deletions
diff --git a/asm/error.c b/asm/error.c index 4e86a0d7..b4ff8bad 100644 --- a/asm/error.c +++ b/asm/error.c @@ -172,18 +172,18 @@ void reset_warnings(void) *! 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). + *! is an group alias for \e{all} 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; + const struct warning_alias *wa; + size_t vlen; bool ok = false; uint8_t mask; - int i; value = nasm_skip_spaces(value); @@ -235,37 +235,48 @@ bool set_warning_status(const char *value) } } - name = value ? value : "<none>"; if (value && !nasm_stricmp(value, "all")) value = NULL; + vlen = value ? strlen(value) : 0; + /* This is inefficient, but it shouldn't matter... */ - 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: - warning_state[i] &= ~mask; - break; - case WID_ON: - warning_state[i] |= mask; - break; - case WID_RESET: - warning_state[i] &= ~mask; - warning_state[i] |= - warning_state_init->state[i] & mask; - break; - } - } - } + for (wa = warning_alias; wa < &warning_alias[NUM_WARNING_ALIAS]; wa++) { + enum warn_index i = wa->warning; - 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_warn(WARN_UNKNOWN_WARNING, "unknown warning name: %s", name); + if (value) { + char sep; + + if (nasm_strnicmp(value, wa->name, vlen)) + continue; /* Not a prefix */ + + sep = wa->name[vlen]; + if (sep != '\0' && sep != '-') + continue; /* Not a valid prefix */ + } + + ok = true; /* At least one action taken */ + switch (action) { + case WID_OFF: + warning_state[i] &= ~mask; + break; + case WID_ON: + warning_state[i] |= mask; + break; + case WID_RESET: + warning_state[i] &= ~mask; + warning_state[i] |= warning_state_init->state[i] & mask; + break; + } + } + + if (!ok && value) { + /*! + *!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_warn(WARN_UNKNOWN_WARNING, "unknown warning name: %s", value); } return ok; @@ -201,7 +201,7 @@ nasm_set_limit(const char *limit, const char *valstr) if (not_started()) errlevel = ERR_WARNING|WARN_OTHER|ERR_USAGE; else - errlevel = ERR_WARNING|WARN_UNKNOWN_PRAGMA; + errlevel = ERR_WARNING|WARN_PRAGMA_UNKNOWN; nasm_error(errlevel, "unknown limit: `%s'", limit); return DIRR_ERROR; } @@ -214,7 +214,7 @@ nasm_set_limit(const char *limit, const char *valstr) if (not_started()) errlevel = ERR_WARNING|WARN_OTHER|ERR_USAGE; else - errlevel = ERR_WARNING|WARN_BAD_PRAGMA; + errlevel = ERR_WARNING|WARN_PRAGMA_BAD; nasm_error(errlevel, "invalid limit value: `%s'", limit); return DIRR_ERROR; } diff --git a/asm/parser.c b/asm/parser.c index fce973b9..60a8964e 100644 --- a/asm/parser.c +++ b/asm/parser.c @@ -460,12 +460,13 @@ restart_parse: i = stdscan(NULL, &tokval); } else if (i == 0) { /*! - *!orphan-labels [on] labels alone on lines without trailing `:' + *!label-orphan [on] labels alone on lines without trailing `:' + *!=orphan-labels *! 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_warn(WARN_ORPHAN_LABELS , + nasm_warn(WARN_LABEL_ORPHAN , "label alone on a line without a colon might be in error"); } if (i != TOKEN_INSN || tokval.t_integer != I_EQU) { diff --git a/asm/pragma.c b/asm/pragma.c index 88f8ae73..9d847070 100644 --- a/asm/pragma.c +++ b/asm/pragma.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * Copyright 1996-2019 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -144,20 +144,22 @@ found_it: switch (pragma->opcode) { case D_none: /*! - *!bad-pragma [off] empty or malformed %pragma + *!pragma-bad [off] empty or malformed %pragma + *!=bad-pragma *! warns about a malformed or otherwise unparsable *! \c{%pragma} directive. */ - nasm_error(ERR_WARNING|ERR_PASS2|WARN_BAD_PRAGMA, + nasm_error(ERR_WARNING|ERR_PASS2|WARN_PRAGMA_BAD, "empty %%pragma %s", pragma->facility_name); break; default: /*! - *!unknown-pragma [off] unknown %pragma facility or directive + *!pragma-unknown [off] unknown %pragma facility or directive + *!=unknown-pragma *! warns about an unknown \c{%pragma} directive. *! This is not yet implemented for most cases. */ - nasm_error(ERR_WARNING|ERR_PASS2|WARN_UNKNOWN_PRAGMA, + nasm_error(ERR_WARNING|ERR_PASS2|WARN_PRAGMA_UNKNOWN, "unknown %%pragma %s %s", pragma->facility_name, pragma->opname); break; @@ -185,7 +187,8 @@ found_it: /* This warning message is intended for future use */ /*! - *!not-my-pragma [off] %pragma not applicable to this compilation + *!pragma-na [off] %pragma not applicable to this compilation + *!=not-my-pragma *! warns about a \c{%pragma} directive which is not applicable to *! this particular assembly session. This is not yet implemented. */ @@ -199,7 +202,7 @@ void process_pragma(char *str) pragma.facility_name = nasm_get_word(str, &p); if (!pragma.facility_name) { - nasm_error(ERR_WARNING|ERR_PASS2|WARN_BAD_PRAGMA, + nasm_error(ERR_WARNING|ERR_PASS2|WARN_PRAGMA_BAD, "empty pragma directive"); return; /* Empty pragma */ } diff --git a/asm/warnings.pl b/asm/warnings.pl index 0c2ed516..d30aecd5 100755 --- a/asm/warnings.pl +++ b/asm/warnings.pl @@ -5,6 +5,8 @@ use File::Find; use File::Basename; my @warnings = (); +my %aliases = (); +my %prefixes = (); my $err = 0; my $nwarn = 0; @@ -15,6 +17,22 @@ sub quote_for_c($) { return $s; } +sub add_alias($$) { + my($a, $this) = @_; + my @comp = split(/-/, $a); + + $aliases{$a} = $this; + + # All names are prefixes in their own right, although we only + # list the ones that are either prefixes of "proper names" or + # the complete alias name. + for (my $i = ($a eq $this->{name}) ? 0 : $#comp; $i <= $#comp; $i++) { + my $prefix = join('-', @comp[0..$i]); + $prefixes{$prefix} = [] unless defined($prefixes{$prefix}); + push(@{$prefixes{$prefix}}, $a); + } +} + sub find_warnings { my $infile = $_; @@ -51,9 +69,9 @@ sub find_warnings { 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(.*\S)\s*$/) { my $name = $1; my $def = $2; my $help = $3; @@ -62,10 +80,17 @@ sub find_warnings { $cname =~ s/[^A-Z0-9_]+/_/g; $this = {name => $name, cname => $cname, - def => $def, help => $help, doc => [], - file => $infile, line => $nline}; + def => $def, help => $help, + doc => [], file => $infile, line => $nline}; push(@warnings, $this); + # Every warning name is also a valid warning alias + add_alias($name, $this); $nwarn++; + } elsif (defined($this) && $str =~ /^\=([\w-,]+)\s*$/) { + # Alias names for warnings + for my $a (split(/,+/, $1)) { + add_alias($a, $this); + } } else { print STDERR "$infile:$nline: malformed warning definition\n"; print STDERR " $l\n"; @@ -115,6 +140,16 @@ if ($what eq 'c') { print $out ",\n\t\"", $warn->{name}, "\""; } print $out "\n};\n\n"; + printf $out "const struct warning_alias warning_alias[NUM_WARNING_ALIAS] = {", + scalar(%aliases); + my $sep = ''; + foreach my $alias (sort { $a cmp $b } keys(%aliases)) { + printf $out "%s\n\t{ %-27s WARN_IDX_%s }", + $sep, "\"$alias\",", $aliases{$alias}->{cname}; + $sep = ','; + } + print $out "\n};\n\n"; + printf $out "const char * const warning_help[%d] = {\n", $#warnings + 2; print $out "\tNULL"; @@ -164,10 +199,17 @@ if ($what eq 'c') { } print $out "\n};\n\n"; + print $out "struct warning_alias {\n"; + print $out "\tconst char *name;\n"; + print $out "\tenum warn_index warning;\n"; + print $out "};\n\n"; + printf $out "#define NUM_WARNING_ALIAS %d\n", scalar(%aliases); + printf $out "extern const char * const warning_name[%d];\n", $#warnings + 2; printf $out "extern const char * const warning_help[%d];\n", $#warnings + 2; + print $out "extern const struct warning_alias warning_alias[NUM_WARNING_ALIAS];\n"; printf $out "extern const uint8_t warning_default[%d];\n", $#warn_noall + 2; printf $out "extern uint8_t warning_state[%d];\n", @@ -177,20 +219,44 @@ if ($what eq 'c') { my %whatdef = ( 'on' => 'Enabled', 'off' => 'Disabled', 'err' => 'Enabled and promoted to error' ); - foreach my $warn (@warnings) { - my @doc = @{$warn->{doc}}; - shift @doc while ($doc[0] =~ /^\s*$/); - pop @doc while ($doc[$#doc] =~ /^\s*$/); + foreach my $pfx (sort { $a cmp $b } keys(%prefixes)) { + my $warn = $aliases{$pfx}; + my @doc; - print $out "\\b \\i\\c{", $warn->{name}, "} ", @doc; + if (!defined($warn)) { + my @plist = sort { $a cmp $b } @{$prefixes{$pfx}}; + next if ( $#plist < 1 ); - my $docdef = $whatdef{$warn->{def}}; - if (defined($docdef)) { - print $out $docdef, " by default.\n"; + @doc = ("is a group alias for all warning classes prefixed by ". + "\\c{".$pfx."-}; currently\n"); + for (my $i = 0; $i <= $#plist; $i++) { + if ($i > 0) { + if ($i < $#plist) { + push(@doc, ", "); + } else { + push(@doc, ($i == 1) ? " and " : ", and "); + } + } + push(@doc, '\c{'.$plist[$i].'}'); + } + push(@doc, ".\n"); + } elsif ($pfx ne $warn->{name}) { + @doc = ("is a backwards compatibility alias for \\c{", + $warn->{name}, "}.\n"); + } else { + my $docdef = $whatdef{$warn->{def}}; + + @doc = @{$warn->{doc}}; + shift @doc while ($doc[0] =~ /^\s*$/); + pop @doc while ($doc[$#doc] =~ /^\s*$/); + + if (defined($docdef)) { + push(@doc, "$docdef by default.\n"); + } } - print $out "\n"; + print $out "\\b \\i\\c{", $pfx, "} ", @doc, "\n"; } } close($out); @@ -126,11 +126,11 @@ OPTIONS *-W[no-]foo':: Causes *nasm* to enable or disable certain classes of warning messages, - in gcc-like style, for example *-Worphan-labels* or *-Wno-orphan-labels*. + in gcc-like style, for example *-Wlabel-orphan* or *-Wno-orphan-labels*. *-w*'[+-]foo':: Causes *nasm* to enable or disable certain classes of warning messages, - for example *-w+orphan-labels* or *-w-macro-params*. + for example *-w+label-orphan* or *-w-macro-params*. *-X* 'format':: Specifies error reporting format (gnu or vc). diff --git a/output/outdbg.c b/output/outdbg.c index 2bf176cb..3c1f42f2 100644 --- a/output/outdbg.c +++ b/output/outdbg.c @@ -371,7 +371,7 @@ dbg_pragma(const struct pragma *pragma) errno = 0; arg = strtoul(pragma->tail, &ep, 0); if (errno || *nasm_skip_spaces(ep)) { - nasm_error(ERR_WARNING | WARN_BAD_PRAGMA | ERR_PASS2, + nasm_error(ERR_WARNING | WARN_PRAGMA_BAD | ERR_PASS2, "invalid %%pragma dbg maxdump argument"); return DIRR_ERROR; } else { diff --git a/test/br3392538.asm b/test/br3392538.asm index 3d9f5186..54e8f08d 100644 --- a/test/br3392538.asm +++ b/test/br3392538.asm @@ -17,7 +17,7 @@ _start: ; either of the following lines cause: Error in `nasm': double free or corruption ; Aborted (core dumped) foo -; warning: label alone on a line without a colon might be in error [-w+orphan-labels] +; warning: label alone on a line without a colon might be in error [-w+label-orphan] mov r8, r9, r10 ; error: invalid combination of opcode and operands add r8d, byte 80h diff --git a/travis/test/aoutso.stderr b/travis/test/aoutso.stderr index 5b135f21..a1e07239 100644 --- a/travis/test/aoutso.stderr +++ b/travis/test/aoutso.stderr @@ -1 +1 @@ -./travis/test/aoutso.asm:79: warning: label alone on a line without a colon might be in error [-w+orphan-labels]
\ No newline at end of file +./travis/test/aoutso.asm:79: warning: label alone on a line without a colon might be in error [-w+label-orphan]
\ No newline at end of file diff --git a/travis/test/elfso-o0.stderr b/travis/test/elfso-o0.stderr index 77bf808f..bffa758b 100644 --- a/travis/test/elfso-o0.stderr +++ b/travis/test/elfso-o0.stderr @@ -1 +1 @@ -./travis/test/elfso.asm:83: warning: label alone on a line without a colon might be in error [-w+orphan-labels]
\ No newline at end of file +./travis/test/elfso.asm:83: warning: label alone on a line without a colon might be in error [-w+label-orphan]
\ No newline at end of file diff --git a/travis/test/elfso-ox.stderr b/travis/test/elfso-ox.stderr index 77bf808f..bffa758b 100644 --- a/travis/test/elfso-ox.stderr +++ b/travis/test/elfso-ox.stderr @@ -1 +1 @@ -./travis/test/elfso.asm:83: warning: label alone on a line without a colon might be in error [-w+orphan-labels]
\ No newline at end of file +./travis/test/elfso.asm:83: warning: label alone on a line without a colon might be in error [-w+label-orphan]
\ No newline at end of file diff --git a/travis/test/tmap.o.stderr b/travis/test/tmap.o.stderr index cf2770e8..3cf4d563 100644 --- a/travis/test/tmap.o.stderr +++ b/travis/test/tmap.o.stderr @@ -1 +1 @@ -./travis/test/tmap.asm:938: warning: label alone on a line without a colon might be in error [-w+orphan-labels]
\ No newline at end of file +./travis/test/tmap.asm:938: warning: label alone on a line without a colon might be in error [-w+label-orphan]
\ No newline at end of file |