1
0
mirror of https://github.com/golang/go synced 2024-11-25 14:07:56 -07:00

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
This commit is contained in:
Russ Cox 2009-10-12 11:03:48 -07:00
parent add89dd1ba
commit 2372408189
8 changed files with 135 additions and 50 deletions

View File

@ -1193,10 +1193,8 @@ addmethod(Sym *sf, Type *t, int local)
fatal("addmethod: not TFIELD: %N", f);
if(strcmp(sf->name, f->sym->name) != 0)
continue;
if(!eqtype(t, f->type)) {
yyerror("method redeclared: %T.%S", pa, sf);
print("\t%T\n\t%T\n", f->type, t);
}
if(!eqtype(t, f->type))
yyerror("method redeclared: %T.%S\n\t%T\n\t%T", pa, sf, f->type, t);
return;
}

View File

@ -792,6 +792,8 @@ Sym* pkglookup(char*, char*);
Sym* restrictlookup(char*, char*);
void importdot(Sym*, Node*);
void yyerror(char*, ...);
void yyerrorl(int, char*, ...);
void flusherrors(void);
int parserline(void);
void warn(char*, ...);
void fatal(char*, ...);

View File

@ -1191,7 +1191,8 @@ xdcl_list:
| xdcl_list xdcl
{
$$ = concat($1, $2);
testdclstack();
if(nsyntaxerrors == 0)
testdclstack();
}
vardcl_list:

View File

@ -1476,19 +1476,16 @@ mkpackage(char* pkg)
// TODO(rsc): remember that there was a package
// name, so that the name cannot be redeclared
// as a non-package in other files.
if(!s->def->used) {
print("%L: imported and not used: %s\n", s->def->lineno, s->def->sym->name);
nerrors++;
}
if(!s->def->used && !nsyntaxerrors)
yyerrorl(s->def->lineno, "imported and not used: %s", s->def->sym->name);
s->def = N;
continue;
}
if(s->def->sym != s) {
// throw away top-level name left over
// from previous import . "x"
if(s->def->pack != N && !s->def->pack->used) {
print("%L: imported and not used: %s\n", s->def->pack->lineno, s->def->pack->sym->name);
nerrors++;
if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
yyerrorl(s->def->pack->lineno, "imported and not used: %s", s->def->pack->sym->name);
s->def->pack->used = 1;
}
s->def = N;

View File

@ -7,9 +7,21 @@
#include "y.tab.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
errorexit(void)
{
flusherrors();
if(outfile)
remove(outfile);
exit(1);
@ -24,26 +36,106 @@ parserline(void)
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
yyerror(char *fmt, ...)
{
va_list arg;
if(strcmp(fmt, "syntax error") == 0) {
print("%L: syntax error near %s\n", lexlineno, lexbuf);
yyerrorl(lexlineno, "syntax error near %s", lexbuf);
nsyntaxerrors++;
goto out;
return;
}
print("%L: ", parserline());
va_start(arg, fmt);
vfprint(1, fmt, arg);
adderr(parserline(), fmt, arg);
va_end(arg);
print("\n");
out:
if(debug['h'])
*(int*)0 = 0;
hcrash();
nerrors++;
if(nerrors >= 10 && !debug['e'])
fatal("too many errors");
@ -54,13 +146,11 @@ warn(char *fmt, ...)
{
va_list arg;
print("%L: ", lineno);
va_start(arg, fmt);
vfprint(1, fmt, arg);
adderr(parserline(), fmt, arg);
va_end(arg);
print("\n");
if(debug['h'])
*(int*)0 = 0;
hcrash();
}
void
@ -68,16 +158,15 @@ fatal(char *fmt, ...)
{
va_list arg;
flusherrors();
print("%L: fatal error: ", lineno);
va_start(arg, fmt);
vfprint(1, fmt, arg);
va_end(arg);
print("\n");
if(debug['h']) {
if(outfile)
unlink(outfile);
*(int*)0 = 0;
}
hcrash();
errorexit();
}
@ -269,8 +358,7 @@ importdot(Sym *opkg, Node *pack)
}
if(n == 0) {
// can't possibly be used - there were no symbols
print("%L: imported and not used: %s\n", pack->lineno, pack->sym->name);
nerrors++;
yyerrorl(pack->lineno, "imported and not used: %s", pack->sym->name);
}
}
@ -285,6 +373,7 @@ gethunk(void)
nh = 10L*NHUNK;
h = (char*)malloc(nh);
if(h == (char*)-1) {
flusherrors();
yyerror("out of memory");
errorexit();
}
@ -2846,19 +2935,21 @@ runifacechecks(void)
needexplicit = 1;
}
if(wrong) {
yyerror("%T is not %T\n\tmissing %S%hhT",
t, iface, m->sym, m->type);
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) {
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)
print("\tdo have %S%hhT\n", samename->sym, samename->type);
}
else
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
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",
p->src, p->dst);
}

View File

@ -395,9 +395,7 @@ mkcaselist(Node *sw, int arg)
if(typecmp(c1, c1->link) != 0)
continue;
setlineno(c1->link->node);
yyerror("duplicate case in switch");
print("\tprevious case at %L\n",
c1->node->lineno);
yyerror("duplicate case in switch\n\tprevious case at %L", c1->node->lineno);
}
break;
case Snorm:
@ -408,9 +406,7 @@ mkcaselist(Node *sw, int arg)
if(exprcmp(c1, c1->link) != 0)
continue;
setlineno(c1->link->node);
yyerror("duplicate case in switch");
print("\tprevious case at %L\n",
c1->node->lineno);
yyerror("duplicate case in switch\n\tprevious case at %L", c1->node->lineno);
}
break;
}

View File

@ -87,7 +87,7 @@ walk(Node *fn)
continue;
lineno = n->lineno;
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);
}
lineno = lno;

View File

@ -152,11 +152,11 @@ BUG: errchk: command succeeded unexpectedly
=========== bugs/bug190.go
bugs/bug190.go:11: 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: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
BUG: should compile
=========== bugs/bug193.go