mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-02-17 17:19:35 +08:00
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:
parent
34ec300643
commit
00835fec0e
62
nasm.c
62
nasm.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user