summaryrefslogtreecommitdiff
path: root/src/cmd/gc/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/subr.c')
-rw-r--r--src/cmd/gc/subr.c63
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)