diff options
Diffstat (limited to 'src/cmd/gc')
-rw-r--r-- | src/cmd/gc/align.c | 5 | ||||
-rw-r--r-- | src/cmd/gc/go.h | 1 | ||||
-rw-r--r-- | src/cmd/gc/inl.c | 9 | ||||
-rw-r--r-- | src/cmd/gc/subr.c | 9 | ||||
-rw-r--r-- | src/cmd/gc/typecheck.c | 2 |
5 files changed, 22 insertions, 4 deletions
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c index 6e5d149c7..63ed2e5af 100644 --- a/src/cmd/gc/align.c +++ b/src/cmd/gc/align.c @@ -128,6 +128,11 @@ dowidth(Type *t) return; } + // break infinite recursion if the broken recursive type + // is referenced again + if(t->broke && t->width == 0) + return; + // defer checkwidth calls until after we're done defercalc++; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 965a0550d..bbb883513 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -974,6 +974,7 @@ EXTERN int funcdepth; EXTERN int typecheckok; EXTERN int compiling_runtime; EXTERN int compiling_wrappers; +EXTERN int inl_nonlocal; EXTERN int use_writebarrier; EXTERN int pure_go; EXTERN char* flag_installsuffix; diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c index cf89b0090..45e15bb9b 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -804,9 +804,12 @@ inlvar(Node *var) n->curfn = curfn; // the calling function, not the called one n->addrtaken = var->addrtaken; - // esc pass wont run if we're inlining into a iface wrapper - // luckily, we can steal the results from the target func - if(var->esc == EscHeap) + // Esc pass wont run if we're inlining into a iface wrapper. + // Luckily, we can steal the results from the target func. + // If inlining a function defined in another package after + // escape analysis is done, treat all local vars as escaping. + // See issue 9537. + if(var->esc == EscHeap || (inl_nonlocal && var->op == ONAME)) addrescapes(n); curfn->dcl = list(curfn->dcl, n); diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index c3bc5af3b..26153d39b 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -2614,7 +2614,16 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface) fn->dupok = 1; typecheck(&fn, Etop); typechecklist(fn->nbody, Etop); + + // Set inl_nonlocal to whether we are calling a method on a + // type defined in a different package. Checked in inlvar. + if(!methodrcvr->local) + inl_nonlocal = 1; + inlcalls(fn); + + inl_nonlocal = 0; + curfn = nil; funccompile(fn, 0); } diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 714c66268..ce12f150a 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -1335,7 +1335,7 @@ reswitch: goto error; // Unpack multiple-return result before type-checking. - if(istype(t, TSTRUCT)) { + if(istype(t, TSTRUCT) && t->funarg) { t = t->type; if(istype(t, TFIELD)) t = t->type; |