diff options
Diffstat (limited to 'src/cmd/gc')
-rw-r--r-- | src/cmd/gc/Makefile | 2 | ||||
-rw-r--r-- | src/cmd/gc/dcl.c | 35 | ||||
-rw-r--r-- | src/cmd/gc/doc.go | 2 | ||||
-rw-r--r-- | src/cmd/gc/go.h | 4 | ||||
-rw-r--r-- | src/cmd/gc/inl.c | 2 | ||||
-rw-r--r-- | src/cmd/gc/lex.c | 2 | ||||
-rw-r--r-- | src/cmd/gc/obj.c | 32 | ||||
-rw-r--r-- | src/cmd/gc/reflect.c | 6 | ||||
-rw-r--r-- | src/cmd/gc/runtime.go | 2 | ||||
-rw-r--r-- | src/cmd/gc/subr.c | 28 | ||||
-rw-r--r-- | src/cmd/gc/typecheck.c | 62 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 14 |
12 files changed, 139 insertions, 52 deletions
diff --git a/src/cmd/gc/Makefile b/src/cmd/gc/Makefile index df34c05b2..58e25faaf 100644 --- a/src/cmd/gc/Makefile +++ b/src/cmd/gc/Makefile @@ -6,7 +6,7 @@ include ../../Make.dist install: y.tab.h builtin.c -y.tab.h: go.y +y.tab.h: go.y go.errors bisonerrors bison -v -y -d go.y # make yystate global, yytname mutable cat y.tab.c | sed '/ int yystate;/d; s/int yychar;/int yychar, yystate;/; s/static const char \*const yytname/const char *yytname/; s/char const \*yymsgp/char *yymsgp/' >y1.tab.c diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 4a0e7430a..4121a45ab 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -1168,21 +1168,22 @@ methodsym(Sym *nsym, Type *t0, int iface) char *p; Type *t; char *suffix; + Pkg *spkg; + static Pkg *toppkg; t = t0; if(t == T) goto bad; s = t->sym; - if(s == S) { - if(!isptr[t->etype]) - goto bad; + if(s == S && isptr[t->etype]) { t = t->type; if(t == T) goto bad; s = t->sym; - if(s == S) - goto bad; } + spkg = nil; + if(s != S) + spkg = s->pkg; // if t0 == *t and t0 has a sym, // we want to see *t, not t0, in the method name. @@ -1195,11 +1196,23 @@ methodsym(Sym *nsym, Type *t0, int iface) if(t0->width < types[tptr]->width) suffix = "·i"; } - if(t0->sym == S && isptr[t0->etype]) - p = smprint("(%-hT).%s%s", t0, nsym->name, suffix); - else - p = smprint("%-hT.%s%s", t0, nsym->name, suffix); - s = pkglookup(p, s->pkg); + if((spkg == nil || nsym->pkg != spkg) && !exportname(nsym->name)) { + if(t0->sym == S && isptr[t0->etype]) + p = smprint("(%-hT).%s.%s%s", t0, nsym->pkg->prefix, nsym->name, suffix); + else + p = smprint("%-hT.%s.%s%s", t0, nsym->pkg->prefix, nsym->name, suffix); + } else { + if(t0->sym == S && isptr[t0->etype]) + p = smprint("(%-hT).%s%s", t0, nsym->name, suffix); + else + p = smprint("%-hT.%s%s", t0, nsym->name, suffix); + } + if(spkg == nil) { + if(toppkg == nil) + toppkg = mkpkg(strlit("go")); + spkg = toppkg; + } + s = pkglookup(p, spkg); free(p); return s; @@ -1268,7 +1281,7 @@ addmethod(Sym *sf, Type *t, int local) } pa = pa->type; - f = methtype(pa); + f = methtype(pa, 1); if(f == T) { t = pa; if(t != T) { diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go index 5a2977eab..163d3862c 100644 --- a/src/cmd/gc/doc.go +++ b/src/cmd/gc/doc.go @@ -26,7 +26,7 @@ package P to read the files of P's dependencies, only the compiled output of P. Usage: - 6g [flags] file... + go tool 6g [flags] file... The specified files must be Go source files and all part of the same package. Substitute 6g with 8g or 5g where appropriate. diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 753360e46..8c4fff15a 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -1154,7 +1154,7 @@ int cplxsubtype(int et); int eqtype(Type *t1, Type *t2); int eqtypenoname(Type *t1, Type *t2); void errorexit(void); -void expandmeth(Sym *s, Type *t); +void expandmeth(Type *t); void fatal(char *fmt, ...); void flusherrors(void); void frame(int context); @@ -1192,7 +1192,7 @@ NodeList* listtreecopy(NodeList *l); Sym* lookup(char *name); void* mal(int32 n); Type* maptype(Type *key, Type *val); -Type* methtype(Type *t); +Type* methtype(Type *t, int mustname); Pkg* mkpkg(Strlit *path); Sym* ngotype(Node *n); int noconv(Type *t1, Type *t2); diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c index 96080cbfa..efce56057 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -182,6 +182,8 @@ ishairy(Node *n, int *budget) case OCALLFUNC: case OCALLINTER: case OCALLMETH: + case OPANIC: + case ORECOVER: if(debug['l'] < 4) return 1; break; diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index 96786b5e6..e71fd3848 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -514,7 +514,7 @@ addidir(char* dir) static int islocalname(Strlit *name) { - if(!windows && name->len >= 1 && name->s[0] == '/') + if(name->len >= 1 && name->s[0] == '/') return 1; if(windows && name->len >= 3 && yy_isalpha(name->s[0]) && name->s[1] == ':' && name->s[2] == '/') diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c index aae566dbb..e45b4e0d4 100644 --- a/src/cmd/gc/obj.c +++ b/src/cmd/gc/obj.c @@ -126,10 +126,37 @@ outhist(Biobuf *b) { Hist *h; char *p, ds[] = {'c', ':', '/', 0}; + char *tofree; + int n; + static int first = 1; + static char *goroot, *goroot_final; + if(first) { + // Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL. + first = 0; + goroot = getenv("GOROOT"); + goroot_final = getenv("GOROOT_FINAL"); + if(goroot == nil) + goroot = ""; + if(goroot_final == nil) + goroot_final = goroot; + if(strcmp(goroot, goroot_final) == 0) { + goroot = nil; + goroot_final = nil; + } + } + + tofree = nil; for(h = hist; h != H; h = h->link) { p = h->name; if(p) { + if(goroot != nil) { + n = strlen(goroot); + if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') { + tofree = smprint("%s%s", goroot_final, p+n); + p = tofree; + } + } if(windows) { // if windows variable is set, then, we know already, // pathname is started with windows drive specifier @@ -161,9 +188,12 @@ outhist(Biobuf *b) outzfile(b, p); } } - } zhist(b, h->line, h->offset); + if(tofree) { + free(tofree); + tofree = nil; + } } } diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c index 0847e9a3f..07b426508 100644 --- a/src/cmd/gc/reflect.c +++ b/src/cmd/gc/reflect.c @@ -144,11 +144,11 @@ methods(Type *t) Sig *a, *b; Sym *method; - // named method type - mt = methtype(t); + // method type + mt = methtype(t, 0); if(mt == T) return nil; - expandmeth(mt->sym, mt); + expandmeth(mt); // type stored in interface word it = t; diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index 000b2328f..15a61d9ef 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // NOTE: If you change this file you must run "./mkbuiltin" -// to update builtin.c.boot. This is not done automatically +// to update builtin.c. This is not done automatically // to avoid depending on having a working compiler binary. // +build ignore diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 6eb7734f0..681c023a0 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -944,7 +944,7 @@ isideal(Type *t) * return type to hang methods off (r). */ Type* -methtype(Type *t) +methtype(Type *t, int mustname) { if(t == T) return T; @@ -959,7 +959,7 @@ methtype(Type *t) } // need a type name - if(t->sym == S) + if(t->sym == S && (mustname || t->etype != TSTRUCT)) return T; // check types @@ -2101,7 +2101,7 @@ lookdot0(Sym *s, Type *t, Type **save, int ignorecase) c++; } } - u = methtype(t); + u = methtype(t, 0); if(u != T) { for(f=u->method; f!=T; f=f->down) if(f->embedded == 0 && (f->sym == s || (ignorecase && ucistrcmp(f->sym->name, s->name) == 0))) { @@ -2251,7 +2251,7 @@ expand0(Type *t, int followptr) return; } - u = methtype(t); + u = methtype(t, 0); if(u != T) { for(f=u->method; f!=T; f=f->down) { if(f->sym->flags & SymUniq) @@ -2301,14 +2301,12 @@ out: } void -expandmeth(Sym *s, Type *t) +expandmeth(Type *t) { Symlink *sl; Type *f; int c, d; - if(s == S) - return; if(t == T || t->xmethod != nil) return; @@ -3021,9 +3019,9 @@ implements(Type *t, Type *iface, Type **m, Type **samename, int *ptr) return 1; } - t = methtype(t); + t = methtype(t, 0); if(t != T) - expandmeth(t->sym, t); + expandmeth(t); for(im=iface->type; im; im=im->down) { imtype = methodfunc(im->type, 0); tm = ifacelookdot(im->sym, t, &followptr, 0); @@ -3626,23 +3624,23 @@ isbadimport(Strlit *path) while(*s) { s += chartorune(&r, s); if(r == Runeerror) { - yyerror("import path contains invalid UTF-8 sequence"); + yyerror("import path contains invalid UTF-8 sequence: \"%Z\"", path); return 1; } if(r < 0x20 || r == 0x7f) { - yyerror("import path contains control character"); + yyerror("import path contains control character: \"%Z\"", path); return 1; } if(r == '\\') { - yyerror("import path contains backslash; use slash"); + yyerror("import path contains backslash; use slash: \"%Z\"", path); return 1; } if(isspacerune(r)) { - yyerror("import path contains space character"); + yyerror("import path contains space character: \"%Z\"", path); return 1; } - if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}~", r)) { - yyerror("import path contains invalid character '%C'", r); + if(utfrune("!\"#$%&'()*,:;<=>?[]^`{|}", r)) { + yyerror("import path contains invalid character '%C': \"%Z\"", r, path); return 1; } } diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 90bd24964..e98d53857 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -190,6 +190,46 @@ typecheck(Node **np, int top) return n; } +/* + * does n contain a call or receive operation? + */ +static int callrecvlist(NodeList*); + +static int +callrecv(Node *n) +{ + if(n == nil) + return 0; + + switch(n->op) { + case OCALL: + case OCALLMETH: + case OCALLINTER: + case OCALLFUNC: + case ORECV: + return 1; + } + + return callrecv(n->left) || + callrecv(n->right) || + callrecv(n->ntest) || + callrecv(n->nincr) || + callrecvlist(n->ninit) || + callrecvlist(n->nbody) || + callrecvlist(n->nelse) || + callrecvlist(n->list) || + callrecvlist(n->rlist); +} + +static int +callrecvlist(NodeList *l) +{ + for(; l; l=l->next) + if(callrecv(l->n)) + return 1; + return 0; +} + static void typecheck1(Node **np, int top) { @@ -995,12 +1035,14 @@ reswitch: } break; case TARRAY: - if(t->bound >= 0 && l->op == ONAME) { - r = nod(OXXX, N, N); - nodconst(r, types[TINT], t->bound); - r->orig = n; - n = r; - } + if(t->bound < 0) // slice + break; + if(callrecv(l)) // has call or receive + break; + r = nod(OXXX, N, N); + nodconst(r, types[TINT], t->bound); + r->orig = n; + n = r; break; } n->type = types[TINT]; @@ -1664,11 +1706,11 @@ looktypedot(Node *n, Type *t, int dostrcmp) if(t->sym == S && isptr[t->etype]) tt = t->type; - f2 = methtype(tt); + f2 = methtype(tt, 0); if(f2 == T) return 0; - expandmeth(f2->sym, f2); + expandmeth(f2); f2 = lookdot1(n, s, f2, f2->xmethod, dostrcmp); if(f2 == T) return 0; @@ -1712,7 +1754,7 @@ lookdot(Node *n, Type *t, int dostrcmp) f2 = T; if(n->left->type == t || n->left->type->sym == S) { - f2 = methtype(t); + f2 = methtype(t, 0); if(f2 != T) { // Use f2->method, not f2->xmethod: adddot has // already inserted all the necessary embedded dots. @@ -1964,7 +2006,7 @@ keydup(Node *n, Node *hash[], ulong nhash) b = cmp.val.u.bval; if(b) { // too lazy to print the literal - yyerror("duplicate key in map literal"); + yyerror("duplicate key %N in map literal", n); return; } } diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 74298e126..7dfd34a7a 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -646,12 +646,6 @@ walkexpr(Node **np, NodeList **init) n->ninit = nil; l = n->list->n; r = n->list->next->n; - if(n->right != N) { - // TODO: Remove once two-element map assigment is gone. - l = safeexpr(l, init); - r = safeexpr(r, init); - safeexpr(n->right, init); // cause side effects from n->right - } t = l->type; n = mkcall1(mapfndel("mapdelete", t), t->down, init, typename(t), l, r); goto ret; @@ -2364,6 +2358,12 @@ append(Node *n, NodeList **init) walkexprlistsafe(n->list, init); + // walkexprlistsafe will leave OINDEX (s[n]) alone if both s + // and n are name or literal, but those may index the slice we're + // modifying here. Fix explicitly. + for(l=n->list; l; l=l->next) + l->n = cheapexpr(l->n, init); + nsrc = n->list->n; argc = count(n->list) - 1; if (argc < 1) { @@ -2520,6 +2520,7 @@ walkcompare(Node **np, NodeList **init) expr = nodbool(n->op == OEQ); typecheck(&expr, Erv); walkexpr(&expr, init); + expr->type = n->type; *np = expr; return; } @@ -2540,6 +2541,7 @@ walkcompare(Node **np, NodeList **init) expr = nodbool(n->op == OEQ); typecheck(&expr, Erv); walkexpr(&expr, init); + expr->type = n->type; *np = expr; return; } |