diff options
Diffstat (limited to 'src/cmd/gc/subr.c')
-rw-r--r-- | src/cmd/gc/subr.c | 63 |
1 files changed, 30 insertions, 33 deletions
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index bea90b87b..72a9ac20c 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -88,6 +88,7 @@ flusherrors(void) { int i; + Bflush(&bstdout); if(nerr == 0) return; qsort(err, nerr, sizeof err[0], errcmp); @@ -258,9 +259,6 @@ fatal(char *fmt, ...) void linehist(char *file, int32 off, int relative) { - Hist *h; - char *cp; - if(debug['i']) { if(file != nil) { if(off < 0) @@ -274,25 +272,10 @@ linehist(char *file, int32 off, int relative) print("end of import"); print(" at line %L\n", lexlineno); } - - if(off < 0 && file[0] != '/' && !relative) { - cp = mal(strlen(file) + strlen(pathname) + 2); - sprint(cp, "%s/%s", pathname, file); - file = cp; - } - - h = mal(sizeof(Hist)); - h->name = file; - h->line = lexlineno; - h->offset = off; - h->link = H; - if(ehist == H) { - hist = h; - ehist = h; - return; - } - ehist->link = h; - ehist = h; + + if(off < 0 && file[0] != '/' && !relative) + file = smprint("%s/%s", ctxt->pathname, file); + linklinehist(ctxt, lexlineno, file, off); } int32 @@ -607,8 +590,6 @@ algtype1(Type *t, Type **bad) *bad = t; return ANOEQ; } - if(t->bound == 0) - return AMEM; a = algtype1(t->type, bad); if(a == ANOEQ || a == AMEM) { if(a == ANOEQ && bad) @@ -1242,8 +1223,10 @@ assignop(Type *src, Type *dst, char **why) // 2. src and dst have identical underlying types // and either src or dst is not a named type or - // both are interface types. - if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || src->etype == TINTER)) + // both are empty interface types. + // For assignable but different non-empty interface types, + // we want to recompute the itab. + if(eqtype(src->orig, dst->orig) && (src->sym == S || dst->sym == S || isnilinter(src))) return OCONVNOP; // 3. dst is an interface type and src implements dst. @@ -1251,13 +1234,16 @@ assignop(Type *src, Type *dst, char **why) if(implements(src, dst, &missing, &have, &ptr)) return OCONVIFACE; - // we'll have complained about this method anyway, supress spurious messages. + // we'll have complained about this method anyway, suppress spurious messages. if(have && have->sym == missing->sym && (have->type->broke || missing->type->broke)) return OCONVIFACE; if(why != nil) { if(isptrto(src, TINTER)) *why = smprint(":\n\t%T is pointer to interface, not interface", src); + else if(have && have->sym == missing->sym && have->nointerface) + *why = smprint(":\n\t%T does not implement %T (%S method is marked 'nointerface')", + src, dst, missing->sym); else if(have && have->sym == missing->sym) *why = smprint(":\n\t%T does not implement %T (wrong type for %S method)\n" "\t\thave %S%hhT\n\t\twant %S%hhT", src, dst, missing->sym, @@ -1692,7 +1678,7 @@ typehash(Type *t) md5reset(&d); md5write(&d, (uchar*)p, strlen(p)); free(p); - return md5sum(&d); + return md5sum(&d, nil); } Type* @@ -2115,7 +2101,7 @@ cheapexpr(Node *n, NodeList **init) Node* localexpr(Node *n, Type *t, NodeList **init) { - if(n->op == ONAME && !n->addrtaken && + if(n->op == ONAME && (!n->addrtaken || strncmp(n->sym->name, "autotmp_", 8) == 0) && (n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) && convertop(n->type, t, nil) == OCONVNOP) return n; @@ -2257,6 +2243,7 @@ adddot(Node *n) int c, d; typecheck(&n->left, Etype|Erv); + n->diag |= n->left->diag; t = n->left->type; if(t == T) goto ret; @@ -2506,12 +2493,19 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) Type *tpad, *methodrcvr; int isddd; Val v; + static int linehistdone = 0; if(0 && debug['r']) print("genwrapper rcvrtype=%T method=%T newnam=%S\n", rcvr, method, newnam); - lineno = 1; // less confusing than end of input + lexlineno++; + lineno = lexlineno; + if (linehistdone == 0) { + // All the wrappers can share the same linehist entry. + linehist("<autogenerated>", 0, 0); + linehistdone = 1; + } dclcontext = PEXTERN; markdcl(); @@ -2608,8 +2602,10 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) funcbody(fn); curfn = fn; - // wrappers where T is anonymous (struct{ NamedType }) can be duplicated. - if(rcvr->etype == TSTRUCT || isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT) + // wrappers where T is anonymous (struct or interface) can be duplicated. + if(rcvr->etype == TSTRUCT || + rcvr->etype == TINTER || + isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT) fn->dupok = 1; typecheck(&fn, Etop); typechecklist(fn->nbody, Etop); @@ -3631,7 +3627,8 @@ ngotype(Node *n) * only in the last segment of the path, and it makes for happier * users if we escape that as little as possible. * - * If you edit this, edit ../ld/lib.c:/^pathtoprefix copy too. + * If you edit this, edit ../ld/lib.c:/^pathtoprefix too. + * If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too. */ static char* pathtoprefix(char *s) |