Commit 23724081 authored by Russ Cox's avatar Russ Cox

sort errors by line number

turn off testdclstack and "not used" errors
when there are syntax errors.

BUG=2181825
R=ken
OCL=35606
CL=35608
parent add89dd1
...@@ -1193,10 +1193,8 @@ addmethod(Sym *sf, Type *t, int local) ...@@ -1193,10 +1193,8 @@ addmethod(Sym *sf, Type *t, int local)
fatal("addmethod: not TFIELD: %N", f); fatal("addmethod: not TFIELD: %N", f);
if(strcmp(sf->name, f->sym->name) != 0) if(strcmp(sf->name, f->sym->name) != 0)
continue; continue;
if(!eqtype(t, f->type)) { if(!eqtype(t, f->type))
yyerror("method redeclared: %T.%S", pa, sf); yyerror("method redeclared: %T.%S\n\t%T\n\t%T", pa, sf, f->type, t);
print("\t%T\n\t%T\n", f->type, t);
}
return; return;
} }
......
...@@ -792,6 +792,8 @@ Sym* pkglookup(char*, char*); ...@@ -792,6 +792,8 @@ Sym* pkglookup(char*, char*);
Sym* restrictlookup(char*, char*); Sym* restrictlookup(char*, char*);
void importdot(Sym*, Node*); void importdot(Sym*, Node*);
void yyerror(char*, ...); void yyerror(char*, ...);
void yyerrorl(int, char*, ...);
void flusherrors(void);
int parserline(void); int parserline(void);
void warn(char*, ...); void warn(char*, ...);
void fatal(char*, ...); void fatal(char*, ...);
......
...@@ -1191,6 +1191,7 @@ xdcl_list: ...@@ -1191,6 +1191,7 @@ xdcl_list:
| xdcl_list xdcl | xdcl_list xdcl
{ {
$$ = concat($1, $2); $$ = concat($1, $2);
if(nsyntaxerrors == 0)
testdclstack(); testdclstack();
} }
......
...@@ -1476,19 +1476,16 @@ mkpackage(char* pkg) ...@@ -1476,19 +1476,16 @@ mkpackage(char* pkg)
// TODO(rsc): remember that there was a package // TODO(rsc): remember that there was a package
// name, so that the name cannot be redeclared // name, so that the name cannot be redeclared
// as a non-package in other files. // as a non-package in other files.
if(!s->def->used) { if(!s->def->used && !nsyntaxerrors)
print("%L: imported and not used: %s\n", s->def->lineno, s->def->sym->name); yyerrorl(s->def->lineno, "imported and not used: %s", s->def->sym->name);
nerrors++;
}
s->def = N; s->def = N;
continue; continue;
} }
if(s->def->sym != s) { if(s->def->sym != s) {
// throw away top-level name left over // throw away top-level name left over
// from previous import . "x" // from previous import . "x"
if(s->def->pack != N && !s->def->pack->used) { if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
print("%L: imported and not used: %s\n", s->def->pack->lineno, s->def->pack->sym->name); yyerrorl(s->def->pack->lineno, "imported and not used: %s", s->def->pack->sym->name);
nerrors++;
s->def->pack->used = 1; s->def->pack->used = 1;
} }
s->def = N; s->def = N;
......
...@@ -7,9 +7,21 @@ ...@@ -7,9 +7,21 @@
#include "y.tab.h" #include "y.tab.h"
#include "opnames.h" #include "opnames.h"
typedef struct Error Error;
struct Error
{
int lineno;
int seq;
char *msg;
};
static Error *err;
static int nerr;
static int merr;
void void
errorexit(void) errorexit(void)
{ {
flusherrors();
if(outfile) if(outfile)
remove(outfile); remove(outfile);
exit(1); exit(1);
...@@ -24,26 +36,106 @@ parserline(void) ...@@ -24,26 +36,106 @@ parserline(void)
return lineno; return lineno;
} }
static void
adderr(int line, char *fmt, va_list arg)
{
Fmt f;
Error *p;
fmtstrinit(&f);
fmtprint(&f, "%L: ", line);
fmtvprint(&f, fmt, arg);
fmtprint(&f, "\n");
if(nerr >= merr) {
if(merr == 0)
merr = 16;
else
merr *= 2;
p = realloc(err, merr*sizeof err[0]);
if(p == nil) {
merr = nerr;
flusherrors();
print("out of memory\n");
errorexit();
}
err = p;
}
err[nerr].seq = nerr;
err[nerr].lineno = line;
err[nerr].msg = fmtstrflush(&f);
nerr++;
}
static int
errcmp(const void *va, const void *vb)
{
Error *a, *b;
a = (Error*)va;
b = (Error*)vb;
if(a->lineno != b->lineno)
return a->lineno - b->lineno;
if(a->seq != b->seq)
return a->seq - b->seq;
return 0;
}
void
flusherrors(void)
{
int i;
if(nerr == 0)
return;
qsort(err, nerr, sizeof err[0], errcmp);
for(i=0; i<nerr; i++)
print("%s", err[i].msg);
nerr = 0;
}
static void
hcrash(void)
{
if(debug['h']) {
flusherrors();
if(outfile)
unlink(outfile);
*(int*)0 = 0;
}
}
void
yyerrorl(int line, char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
adderr(line, fmt, arg);
va_end(arg);
hcrash();
nerrors++;
if(nerrors >= 10 && !debug['e'])
fatal("too many errors");
}
void void
yyerror(char *fmt, ...) yyerror(char *fmt, ...)
{ {
va_list arg; va_list arg;
if(strcmp(fmt, "syntax error") == 0) { if(strcmp(fmt, "syntax error") == 0) {
print("%L: syntax error near %s\n", lexlineno, lexbuf); yyerrorl(lexlineno, "syntax error near %s", lexbuf);
nsyntaxerrors++; nsyntaxerrors++;
goto out; return;
} }
print("%L: ", parserline());
va_start(arg, fmt); va_start(arg, fmt);
vfprint(1, fmt, arg); adderr(parserline(), fmt, arg);
va_end(arg); va_end(arg);
print("\n");
out: hcrash();
if(debug['h'])
*(int*)0 = 0;
nerrors++; nerrors++;
if(nerrors >= 10 && !debug['e']) if(nerrors >= 10 && !debug['e'])
fatal("too many errors"); fatal("too many errors");
...@@ -54,13 +146,11 @@ warn(char *fmt, ...) ...@@ -54,13 +146,11 @@ warn(char *fmt, ...)
{ {
va_list arg; va_list arg;
print("%L: ", lineno);
va_start(arg, fmt); va_start(arg, fmt);
vfprint(1, fmt, arg); adderr(parserline(), fmt, arg);
va_end(arg); va_end(arg);
print("\n");
if(debug['h']) hcrash();
*(int*)0 = 0;
} }
void void
...@@ -68,16 +158,15 @@ fatal(char *fmt, ...) ...@@ -68,16 +158,15 @@ fatal(char *fmt, ...)
{ {
va_list arg; va_list arg;
flusherrors();
print("%L: fatal error: ", lineno); print("%L: fatal error: ", lineno);
va_start(arg, fmt); va_start(arg, fmt);
vfprint(1, fmt, arg); vfprint(1, fmt, arg);
va_end(arg); va_end(arg);
print("\n"); print("\n");
if(debug['h']) {
if(outfile) hcrash();
unlink(outfile);
*(int*)0 = 0;
}
errorexit(); errorexit();
} }
...@@ -269,8 +358,7 @@ importdot(Sym *opkg, Node *pack) ...@@ -269,8 +358,7 @@ importdot(Sym *opkg, Node *pack)
} }
if(n == 0) { if(n == 0) {
// can't possibly be used - there were no symbols // can't possibly be used - there were no symbols
print("%L: imported and not used: %s\n", pack->lineno, pack->sym->name); yyerrorl(pack->lineno, "imported and not used: %s", pack->sym->name);
nerrors++;
} }
} }
...@@ -285,6 +373,7 @@ gethunk(void) ...@@ -285,6 +373,7 @@ gethunk(void)
nh = 10L*NHUNK; nh = 10L*NHUNK;
h = (char*)malloc(nh); h = (char*)malloc(nh);
if(h == (char*)-1) { if(h == (char*)-1) {
flusherrors();
yyerror("out of memory"); yyerror("out of memory");
errorexit(); errorexit();
} }
...@@ -2846,19 +2935,21 @@ runifacechecks(void) ...@@ -2846,19 +2935,21 @@ runifacechecks(void)
needexplicit = 1; needexplicit = 1;
} }
if(wrong) { if(wrong) {
yyerror("%T is not %T\n\tmissing %S%hhT",
t, iface, m->sym, m->type);
if(samename) if(samename)
print("\tdo have %S%hhT\n", samename->sym, samename->type); yyerror("%T is not %T\n\tmissing %S%hhT\n\tdo have %S%hhT",
t, iface, m->sym, m->type, samename->sym, samename->type);
else
yyerror("%T is not %T\n\tmissing %S%hhT", t, iface, m->sym, m->type);
} }
else if(!p->explicit && needexplicit) { else if(!p->explicit && needexplicit) {
if(m) { if(m) {
yyerror("need type assertion to use %T as %T\n\tmissing %S%hhT",
p->src, p->dst, m->sym, m->type);
if(samename) if(samename)
print("\tdo have %S%hhT\n", samename->sym, samename->type); yyerror("need type assertion to use %T as %T\n\tmissing %S %hhT\n\tdo have %S%hhT",
} p->src, p->dst, m->sym, m->type, samename->sym, samename->type);
else else
yyerror("need type assertion to use %T as %T\n\tmissing %S%hhT",
p->src, p->dst, m->sym, m->type);
} else
yyerror("need type assertion to use %T as %T", yyerror("need type assertion to use %T as %T",
p->src, p->dst); p->src, p->dst);
} }
......
...@@ -395,9 +395,7 @@ mkcaselist(Node *sw, int arg) ...@@ -395,9 +395,7 @@ mkcaselist(Node *sw, int arg)
if(typecmp(c1, c1->link) != 0) if(typecmp(c1, c1->link) != 0)
continue; continue;
setlineno(c1->link->node); setlineno(c1->link->node);
yyerror("duplicate case in switch"); yyerror("duplicate case in switch\n\tprevious case at %L", c1->node->lineno);
print("\tprevious case at %L\n",
c1->node->lineno);
} }
break; break;
case Snorm: case Snorm:
...@@ -408,9 +406,7 @@ mkcaselist(Node *sw, int arg) ...@@ -408,9 +406,7 @@ mkcaselist(Node *sw, int arg)
if(exprcmp(c1, c1->link) != 0) if(exprcmp(c1, c1->link) != 0)
continue; continue;
setlineno(c1->link->node); setlineno(c1->link->node);
yyerror("duplicate case in switch"); yyerror("duplicate case in switch\n\tprevious case at %L", c1->node->lineno);
print("\tprevious case at %L\n",
c1->node->lineno);
} }
break; break;
} }
......
...@@ -87,7 +87,7 @@ walk(Node *fn) ...@@ -87,7 +87,7 @@ walk(Node *fn)
continue; continue;
lineno = n->lineno; lineno = n->lineno;
typecheck(&n, Erv | Easgn); // only needed for unused variables typecheck(&n, Erv | Easgn); // only needed for unused variables
if(!n->used && n->sym->name[0] != '&') if(!n->used && n->sym->name[0] != '&' && !nsyntaxerrors)
yyerror("%S declared and not used", n->sym); yyerror("%S declared and not used", n->sym);
} }
lineno = lno; lineno = lno;
......
...@@ -152,11 +152,11 @@ BUG: errchk: command succeeded unexpectedly ...@@ -152,11 +152,11 @@ BUG: errchk: command succeeded unexpectedly
=========== bugs/bug190.go =========== bugs/bug190.go
bugs/bug190.go:11: invalid recursive type []S bugs/bug190.go:11: invalid recursive type []S
bugs/bug190.go:13: invalid recursive type chan S
bugs/bug190.go:15: invalid recursive type func(S) (S)
bugs/bug190.go:16: invalid recursive type S bugs/bug190.go:16: invalid recursive type S
bugs/bug190.go:16: invalid recursive type S bugs/bug190.go:16: invalid recursive type S
bugs/bug190.go:13: invalid recursive type chan S
bugs/bug190.go:16: invalid recursive type S bugs/bug190.go:16: invalid recursive type S
bugs/bug190.go:15: invalid recursive type func(S) (S)
BUG: should compile BUG: should compile
=========== bugs/bug193.go =========== bugs/bug193.go
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment