From 23724081896c0965cbbe49f4c339d1c8e1237081 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 12 Oct 2009 11:03:48 -0700 Subject: [PATCH] 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 --- src/cmd/gc/dcl.c | 6 +- src/cmd/gc/go.h | 2 + src/cmd/gc/go.y | 3 +- src/cmd/gc/lex.c | 11 ++-- src/cmd/gc/subr.c | 147 +++++++++++++++++++++++++++++++++++++--------- src/cmd/gc/swt.c | 8 +-- src/cmd/gc/walk.c | 2 +- test/golden.out | 4 +- 8 files changed, 134 insertions(+), 49 deletions(-) diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 2a154ab5a7..fc0cd6b825 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -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; } diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 4cb0d29608..058f839cdd 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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*, ...); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index 45e0292059..35084c0303 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -1191,7 +1191,8 @@ xdcl_list: | xdcl_list xdcl { $$ = concat($1, $2); - testdclstack(); + if(nsyntaxerrors == 0) + testdclstack(); } vardcl_list: diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index b89f26b5b1..6b05972baa 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -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; diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 007344e93b..90ca992de2 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -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= 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); } diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c index 09d8c564d3..1cd4cfaa86 100644 --- a/src/cmd/gc/swt.c +++ b/src/cmd/gc/swt.c @@ -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; } diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index e5aa1e7265..99c105ba9a 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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; diff --git a/test/golden.out b/test/golden.out index 0981e7c901..6db0a1217a 100644 --- a/test/golden.out +++ b/test/golden.out @@ -152,11 +152,11 @@ BUG: errchk: command succeeded unexpectedly =========== bugs/bug190.go 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:13: invalid recursive type chan S bugs/bug190.go:16: invalid recursive type S -bugs/bug190.go:15: invalid recursive type func(S) (S) BUG: should compile =========== bugs/bug193.go -- 2.48.1