Sanitize the pass logic, and only issue PASS1 warnings on pass0 == 1

For PASS1 warnings, only do them when pass0 == 1.  The prior passes
are to be considered training passes.  This is a bit awkward if we
then hit an error, but it's better than n repeated warnings.
This commit is contained in:
H. Peter Anvin 2008-01-08 23:03:57 -08:00
parent 34ec300643
commit 00835fec0e
2 changed files with 30 additions and 33 deletions

62
nasm.c
View File

@ -49,7 +49,7 @@ static efunc report_error;
static int using_debug_info, opt_verbose_info; static int using_debug_info, opt_verbose_info;
bool tasm_compatible_mode = false; bool tasm_compatible_mode = false;
int pass0; int pass0, passn;
int maxbits = 0; int maxbits = 0;
int globalrel = 0; int globalrel = 0;
@ -897,8 +897,7 @@ static void assemble_file(char *fname)
int64_t offs; int64_t offs;
struct tokenval tokval; struct tokenval tokval;
expr *e; expr *e;
int pass, pass_max; int pass_max;
int pass_cnt = 0; /* count actual passes */
if (cmd_sb == 32 && cmd_cpu < IF_386) if (cmd_sb == 32 && cmd_cpu < IF_386)
report_error(ERR_FATAL, "command line: " report_error(ERR_FATAL, "command line: "
@ -906,15 +905,17 @@ static void assemble_file(char *fname)
pass_max = (optimizing > 0 ? optimizing : 0) + 2; /* passes 1, optimizing, then 2 */ pass_max = (optimizing > 0 ? optimizing : 0) + 2; /* passes 1, optimizing, then 2 */
pass0 = !(optimizing > 0); /* start at 1 if not optimizing */ pass0 = !(optimizing > 0); /* start at 1 if not optimizing */
for (pass = 1; pass0 <= 2; pass++) { for (passn = 1; pass0 <= 2; passn++) {
int pass1, pass2; int pass1, pass2;
ldfunc def_label; ldfunc def_label;
pass1 = pass < pass_max ? 1 : 2; /* seq is 1, 1, 1,..., 1, 2 */ pass1 = pass0 == 2 ? 2 : 1; /* 1, 1, 1, ..., 1, 2 */
pass2 = pass > 1 ? 2 : 1; /* seq is 1, 2, 2,..., 2, 2 */ pass2 = passn > 1 ? 2 : 1; /* 1, 2, 2, ..., 2, 2 */
/* pass0 seq is 0, 0, 0,..., 1, 2 */ /* pass0 0, 0, 0, ..., 1, 2 */
def_label = pass > 1 ? redefine_label : define_label; printf("pass = %d (%d,%d,%d)\n", passn, pass0, pass1, pass2);
def_label = passn > 1 ? redefine_label : define_label;
globalbits = sb = cmd_sb; /* set 'bits' to command line default */ globalbits = sb = cmd_sb; /* set 'bits' to command line default */
cpu = cmd_cpu; cpu = cmd_cpu;
@ -926,7 +927,7 @@ static void assemble_file(char *fname)
global_offset_changed = false; /* set by redefine_label */ global_offset_changed = false; /* set by redefine_label */
location.segment = ofmt->section(NULL, pass2, &sb); location.segment = ofmt->section(NULL, pass2, &sb);
globalbits = sb; globalbits = sb;
if (pass > 1) { if (passn > 1) {
saa_rewind(forwrefs); saa_rewind(forwrefs);
forwref = saa_rstruct(forwrefs); forwref = saa_rstruct(forwrefs);
raa_free(offsets); raa_free(offsets);
@ -934,7 +935,7 @@ static void assemble_file(char *fname)
} }
preproc->reset(fname, pass1, report_error, evaluate, &nasmlist); preproc->reset(fname, pass1, report_error, evaluate, &nasmlist);
globallineno = 0; globallineno = 0;
if (pass == 1) if (passn == 1)
location.known = true; location.known = true;
location.offset = offs = GET_CURR_OFFS; location.offset = offs = GET_CURR_OFFS;
@ -973,7 +974,7 @@ static void assemble_file(char *fname)
*q++ = '\0'; *q++ = '\0';
ofmt->symdef(value, 0L, 0L, 3, q); ofmt->symdef(value, 0L, 0L, 3, q);
} }
} else if (pass == 1) { /* pass == 1 */ } else if (passn == 1) {
q = value; q = value;
validid = true; validid = true;
if (!isidstart(*q)) if (!isidstart(*q))
@ -1113,7 +1114,7 @@ static void assemble_file(char *fname)
abs_seg = reloc_seg(e); abs_seg = reloc_seg(e);
abs_offset = reloc_value(e); abs_offset = reloc_value(e);
} }
} else if (pass == 1) } else if (passn == 1)
abs_offset = 0x100; /* don't go near zero in case of / */ abs_offset = 0x100; /* don't go near zero in case of / */
else else
report_error(ERR_PANIC, "invalid ABSOLUTE address " report_error(ERR_PANIC, "invalid ABSOLUTE address "
@ -1134,13 +1135,13 @@ static void assemble_file(char *fname)
} }
*q++ = 0; *q++ = 0;
if (!validid) { if (!validid) {
report_error(pass == 1 ? ERR_NONFATAL : ERR_PANIC, report_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC,
"identifier expected after DEBUG"); "identifier expected after DEBUG");
break; break;
} }
while (*p && isspace(*p)) while (*p && isspace(*p))
p++; p++;
if (pass == pass_max) if (pass0 == 2)
ofmt->current_dfmt->debug_directive(debugid, p); ofmt->current_dfmt->debug_directive(debugid, p);
break; break;
case D_WARNING: /* [WARNING {+|-}warn-name] */ case D_WARNING: /* [WARNING {+|-}warn-name] */
@ -1224,7 +1225,7 @@ static void assemble_file(char *fname)
parse_line(pass1, line, &output_ins, parse_line(pass1, line, &output_ins,
report_error, evaluate, def_label); report_error, evaluate, def_label);
if (!(optimizing > 0) && pass == 2) { if (!(optimizing > 0) && pass0 == 2) {
if (forwref != NULL && globallineno == forwref->lineno) { if (forwref != NULL && globallineno == forwref->lineno) {
output_ins.forw_ref = true; output_ins.forw_ref = true;
do { do {
@ -1238,7 +1239,7 @@ static void assemble_file(char *fname)
} }
if (!(optimizing > 0) && output_ins.forw_ref) { if (!(optimizing > 0) && output_ins.forw_ref) {
if (pass == 1) { if (passn == 1) {
for (i = 0; i < output_ins.operands; i++) { for (i = 0; i < output_ins.operands; i++) {
if (output_ins.oprs[i]. if (output_ins.oprs[i].
opflags & OPFLAG_FORWARD) { opflags & OPFLAG_FORWARD) {
@ -1249,7 +1250,7 @@ static void assemble_file(char *fname)
fwinf->operand = i; fwinf->operand = i;
} }
} }
} else { /* pass == 2 */ } else { /* passn > 1 */
/* /*
* Hack to prevent phase error in the code * Hack to prevent phase error in the code
* rol ax,x * rol ax,x
@ -1277,7 +1278,7 @@ static void assemble_file(char *fname)
output_ins.oprs[1].type &= ~REG_SMASK; output_ins.oprs[1].type &= ~REG_SMASK;
} }
} /* pass == 2 */ }
} }
@ -1330,7 +1331,7 @@ static void assemble_file(char *fname)
report_error(ERR_NONFATAL, report_error(ERR_NONFATAL,
"bad syntax for EQU"); "bad syntax for EQU");
} }
} else { /* pass == 2 */ } else {
/* /*
* Special `..' EQUs get processed here, except * Special `..' EQUs get processed here, except
* `..@' macro processor EQUs which are done above. * `..@' macro processor EQUs which are done above.
@ -1365,7 +1366,7 @@ static void assemble_file(char *fname)
report_error(ERR_NONFATAL, report_error(ERR_NONFATAL,
"bad syntax for EQU"); "bad syntax for EQU");
} }
} /* pass == 2 */ }
} else { /* instruction isn't an EQU */ } else { /* instruction isn't an EQU */
if (pass1 == 1) { if (pass1 == 1) {
@ -1443,7 +1444,7 @@ static void assemble_file(char *fname)
* flagged as an error on pass 2 * flagged as an error on pass 2
*/ */
} else { /* pass == 2 */ } else {
offs += assemble(location.segment, offs, sb, cpu, offs += assemble(location.segment, offs, sb, cpu,
&output_ins, ofmt, report_error, &output_ins, ofmt, report_error,
&nasmlist); &nasmlist);
@ -1471,23 +1472,17 @@ static void assemble_file(char *fname)
usage(); usage();
exit(1); exit(1);
} }
pass_cnt++; if (passn >= pass_max - 2 ||
if ((pass > 1 && !global_offset_changed) || (passn > 1 && !global_offset_changed))
pass >= pass_max - 2) {
pass0++; pass0++;
if (pass0 == 2) }
pass = pass_max - 1;
} else if (!(optimizing > 0))
pass0++;
} /* for (pass=1; pass<=2; pass++) */
preproc->cleanup(0); preproc->cleanup(0);
nasmlist.cleanup(); nasmlist.cleanup();
#if 1 #if 1
if (optimizing > 0 && opt_verbose_info) /* -On and -Ov switches */ if (optimizing > 0 && opt_verbose_info) /* -On and -Ov switches */
fprintf(stdout, fprintf(stdout,
"info:: assembly required 1+%d+1 passes\n", pass_cnt - 2); "info:: assembly required 1+%d+1 passes\n", passn-3);
#endif #endif
} /* exit from assemble_file (...) */ } /* exit from assemble_file (...) */
@ -1628,9 +1623,10 @@ static int is_suppressed_warning(int severity)
(severity & ERR_WARN_MASK) != 0 && (severity & ERR_WARN_MASK) != 0 &&
suppressed[(severity & ERR_WARN_MASK) >> ERR_WARN_SHR]) || suppressed[(severity & ERR_WARN_MASK) >> ERR_WARN_SHR]) ||
/* /*
* See if it's a pass-one only warning and we're not in pass one. * See if it's a pass-one only warning and we're not in pass
* zero or one.
*/ */
((severity & ERR_PASS1) && pass0 == 2); ((severity & ERR_PASS1) && pass0 != 1);
} }
/** /**

1
nasm.h
View File

@ -983,6 +983,7 @@ enum special_tokens {
*/ */
extern int pass0; extern int pass0;
extern int passn; /* Actual pass number */
extern bool tasm_compatible_mode; extern bool tasm_compatible_mode;
extern int optimizing; extern int optimizing;