summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/gc/dcl.c6
-rw-r--r--src/cmd/gc/go.h2
-rw-r--r--src/cmd/gc/go.y3
-rw-r--r--src/cmd/gc/lex.c11
-rw-r--r--src/cmd/gc/subr.c147
-rw-r--r--src/cmd/gc/swt.c8
-rw-r--r--src/cmd/gc/walk.c2
-rw-r--r--test/golden.out4
8 files changed, 134 insertions, 49 deletions
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index 2a154ab5a..fc0cd6b82 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 4cb0d2960..058f839cd 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 45e029205..35084c030 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 b89f26b5b..6b05972ba 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 007344e93..90ca992de 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<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);
}
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index 09d8c564d..1cd4cfaa8 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 e5aa1e726..99c105ba9 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 0981e7c90..6db0a1217 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