} else {
                Fatal("closurename called for %v", Nconv(n, obj.FmtShort))
        }
-       namebuf = fmt.Sprintf("%s.%s%d", outer, prefix, gen)
-       n.Sym = Lookup(namebuf)
+       n.Sym = Lookupf("%s.%s%d", outer, prefix, gen)
        return n.Sym
 }
 
                                // we introduce function param &v *T
                                // and v remains PPARAMREF with &v heapaddr
                                // (accesses will implicitly deref &v).
-                               namebuf = fmt.Sprintf("&%s", v.Sym.Name)
-
-                               addr = newname(Lookup(namebuf))
+                               addr = newname(Lookupf("&%s", v.Sym.Name))
                                addr.Type = Ptrto(v.Type)
                                addr.Class = PPARAM
                                v.Heapaddr = addr
                        } else {
                                // Declare variable holding addresses taken from closure
                                // and initialize in entry prologue.
-                               namebuf = fmt.Sprintf("&%s", v.Sym.Name)
-
-                               addr = newname(Lookup(namebuf))
+                               addr = newname(Lookupf("&%s", v.Sym.Name))
                                addr.Ntype = Nod(OIND, typenod(v.Type), nil)
                                addr.Class = PAUTO
                                addr.Used = true
        var fld *Node
        var n *Node
        for t := getinargx(t0).Type; t != nil; t = t.Down {
-               namebuf = fmt.Sprintf("a%d", i)
+               n = newname(Lookupf("a%d", i))
                i++
-               n = newname(Lookup(namebuf))
                n.Class = PPARAM
                xfunc.Dcl = list(xfunc.Dcl, n)
                callargs = list(callargs, n)
        l = nil
        var retargs *NodeList
        for t := getoutargx(t0).Type; t != nil; t = t.Down {
-               namebuf = fmt.Sprintf("r%d", i)
+               n = newname(Lookupf("r%d", i))
                i++
-               n = newname(Lookup(namebuf))
                n.Class = PPARAMOUT
                xfunc.Dcl = list(xfunc.Dcl, n)
                retargs = list(retargs, n)
 
 
                if n.Left == nil {
                        // Name so that escape analysis can track it. ~r stands for 'result'.
-                       namebuf = fmt.Sprintf("~r%d", gen)
+                       n.Left = newname(Lookupf("~r%d", gen))
                        gen++
-
-                       n.Left = newname(Lookup(namebuf))
                }
 
                // TODO: n->left->missing = 1;
 
                        *nn = *n.Left
                        nn.Orig = nn
-                       namebuf = fmt.Sprintf("~b%d", gen)
+                       nn.Sym = Lookupf("~b%d", gen)
                        gen++
-                       nn.Sym = Lookup(namebuf)
                        n.Left = nn
                }
 
 
 
        // give each tmp a different name so that there
        // a chance to registerizer them
-       namebuf = fmt.Sprintf("autotmp_%.4d", statuniqgen)
-
+       s := Lookupf("autotmp_%.4d", statuniqgen)
        statuniqgen++
-       s := Lookup(namebuf)
        n := Nod(ONAME, nil, nil)
        n.Sym = s
        s.Def = n
 
 
 var nolocalimports int
 
-var namebuf string
-
 var lexbuf bytes.Buffer
 var strbuf bytes.Buffer
 
 
 
 package gc
 
-import "fmt"
-
 //     case OADD:
 //             if(n->right->op == OLITERAL) {
 //                     v = n->right->vconst;
 
 func renameinit() *Sym {
        renameinit_initgen++
-       namebuf = fmt.Sprintf("init.%d", renameinit_initgen)
-       return Lookup(namebuf)
+       return Lookupf("init.%d", renameinit_initgen)
 }
 
 /*
        var r *NodeList
 
        // (1)
-       namebuf = "initdoneĀ·"
-
-       gatevar := newname(Lookup(namebuf))
+       gatevar := newname(Lookup("initdoneĀ·"))
        addvar(gatevar, Types[TUINT8], PEXTERN)
 
        // (2)
        Maxarg = 0
 
-       namebuf = "init"
-
        fn := Nod(ODCLFUNC, nil, nil)
-       initsym := Lookup(namebuf)
+       initsym := Lookup("init")
        fn.Nname = newname(initsym)
        fn.Nname.Defn = fn
        fn.Nname.Ntype = Nod(OTFUNC, nil, nil)
        // (9)
        // could check that it is fn of no args/returns
        for i := 1; ; i++ {
-               namebuf = fmt.Sprintf("init.%d", i)
-               s := Lookup(namebuf)
+               s := Lookupf("init.%d", i)
                if s.Def == nil {
                        break
                }
 
 
 // Synthesize a variable to store the inlined function's results in.
 func retvar(t *Type, i int) *Node {
-       namebuf = fmt.Sprintf("~r%d", i)
-       n := newname(Lookup(namebuf))
+       n := newname(Lookupf("~r%d", i))
        n.Type = t.Type
        n.Class = PAUTO
        n.Used = true
 // Synthesize a variable to store the inlined function's arguments
 // when they come from a multiple return call.
 func argvar(t *Type, i int) *Node {
-       namebuf = fmt.Sprintf("~arg%d", i)
-       n := newname(Lookup(namebuf))
+       n := newname(Lookupf("~arg%d", i))
        n.Type = t.Type
        n.Class = PAUTO
        n.Used = true
 
 func newlabel_inl() *Node {
        newlabel_inl_label++
-       namebuf = fmt.Sprintf(".inlret%.6d", newlabel_inl_label)
-       n := newname(Lookup(namebuf))
+       n := newname(Lookupf(".inlret%.6d", newlabel_inl_label))
        n.Etype = 1 // flag 'safe' for escape analysis (no backjumps)
        return n
 }
 
                strings.HasPrefix(name, "../") || name == ".."
 }
 
-func findpkg(name string) bool {
+func findpkg(name string) (file string, ok bool) {
        if islocalname(name) {
                if safemode != 0 || nolocalimports != 0 {
-                       return false
+                       return "", false
                }
 
                // try .a before .6.  important for building libraries:
                // if there is an array.6 in the array.a library,
                // want to find all of array.a, not just array.6.
-               namebuf = fmt.Sprintf("%s.a", name)
-
-               if obj.Access(namebuf, 0) >= 0 {
-                       return true
+               file = fmt.Sprintf("%s.a", name)
+               if obj.Access(file, 0) >= 0 {
+                       return file, true
                }
-               namebuf = fmt.Sprintf("%s.%c", name, Thearch.Thechar)
-               if obj.Access(namebuf, 0) >= 0 {
-                       return true
+               file = fmt.Sprintf("%s.%c", name, Thearch.Thechar)
+               if obj.Access(file, 0) >= 0 {
+                       return file, true
                }
-               return false
+               return "", false
        }
 
        // local imports should be canonicalized already.
        _ = q
        if path.Clean(name) != name {
                Yyerror("non-canonical import path %q (should be %q)", name, q)
-               return false
+               return "", false
        }
 
        for p := idirs; p != nil; p = p.link {
-               namebuf = fmt.Sprintf("%s/%s.a", p.dir, name)
-               if obj.Access(namebuf, 0) >= 0 {
-                       return true
+               file = fmt.Sprintf("%s/%s.a", p.dir, name)
+               if obj.Access(file, 0) >= 0 {
+                       return file, true
                }
-               namebuf = fmt.Sprintf("%s/%s.%c", p.dir, name, Thearch.Thechar)
-               if obj.Access(namebuf, 0) >= 0 {
-                       return true
+               file = fmt.Sprintf("%s/%s.%c", p.dir, name, Thearch.Thechar)
+               if obj.Access(file, 0) >= 0 {
+                       return file, true
                }
        }
 
                        suffix = "race"
                }
 
-               namebuf = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.a", goroot, goos, goarch, suffixsep, suffix, name)
-               if obj.Access(namebuf, 0) >= 0 {
-                       return true
+               file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.a", goroot, goos, goarch, suffixsep, suffix, name)
+               if obj.Access(file, 0) >= 0 {
+                       return file, true
                }
-               namebuf = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.%c", goroot, goos, goarch, suffixsep, suffix, name, Thearch.Thechar)
-               if obj.Access(namebuf, 0) >= 0 {
-                       return true
+               file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.%c", goroot, goos, goarch, suffixsep, suffix, name, Thearch.Thechar)
+               if obj.Access(file, 0) >= 0 {
+                       return file, true
                }
        }
 
-       return false
+       return "", false
 }
 
 func fakeimport() {
                }
        }
 
-       if !findpkg(path_) {
+       file, found := findpkg(path_)
+       if !found {
                Yyerror("can't find import: %q", f.U.Sval)
                errorexit()
        }
        // If we already saw that package, feed a dummy statement
        // to the lexer to avoid parsing export data twice.
        if importpkg.Imported != 0 {
-               file := namebuf
                tag := ""
                if importpkg.Safe {
                        tag = "safe"
 
        var err error
        var imp *obj.Biobuf
-       imp, err = obj.Bopenr(namebuf)
+       imp, err = obj.Bopenr(file)
        if err != nil {
                Yyerror("can't open import: %q: %v", f.U.Sval, err)
                errorexit()
        }
 
-       file := namebuf
-
-       n := len(namebuf)
-       if n > 2 && namebuf[n-2] == '.' && namebuf[n-1] == 'a' {
+       if strings.HasSuffix(file, ".a") {
                if !skiptopkgdef(imp) {
                        Yyerror("import %s: not a package file", file)
                        errorexit()
 
        // assume files move (get installed)
        // so don't record the full path.
-       linehist(file[n-len(path_)-2:], -1, 1) // acts as #pragma lib
+       linehist(file[len(file)-len(path_)-2:], -1, 1) // acts as #pragma lib
 
        /*
         * position the input right
                                p = p[i+1:]
                        }
                }
-               namebuf = p
-               if i := strings.LastIndex(namebuf, "."); i >= 0 {
-                       namebuf = namebuf[:i]
+               if i := strings.LastIndex(p, "."); i >= 0 {
+                       p = p[:i]
                }
-               outfile = fmt.Sprintf("%s.%c", namebuf, Thearch.Thechar)
+               outfile = fmt.Sprintf("%s.%c", p, Thearch.Thechar)
        }
 }
 
                        obj.Bputc(bout, 0)
                }
                obj.Bseek(bout, startobj-ArhdrSize, 0)
-               namebuf = fmt.Sprintf("_go_.%c", Thearch.Thechar)
-               formathdr(arhdr[:], namebuf, size)
+               name := fmt.Sprintf("_go_.%c", Thearch.Thechar)
+               formathdr(arhdr[:], name, size)
                obj.Bwrite(bout, arhdr[:])
        }
 
 var stringsym_gen int
 
 func stringsym(s string) *Sym {
+       var symname string
        var pkg *Pkg
        if len(s) > 100 {
                // huge strings are made static to avoid long names
                stringsym_gen++
-               namebuf = fmt.Sprintf(".gostring.%d", stringsym_gen)
+               symname = fmt.Sprintf(".gostring.%d", stringsym_gen)
 
                pkg = localpkg
        } else {
                // small strings get named by their contents,
                // so that multiple modules using the same string
                // can share it.
-               namebuf = fmt.Sprintf("%q", s)
+               symname = fmt.Sprintf("%q", s)
                pkg = gostringpkg
        }
 
-       sym := Pkglookup(namebuf, pkg)
+       sym := Pkglookup(symname, pkg)
 
        // SymUniq flag indicates that data is generated already
        if sym.Flags&SymUniq != 0 {
        var m int
 
        slicebytes_gen++
-       namebuf = fmt.Sprintf(".gobytes.%d", slicebytes_gen)
-       sym := Pkglookup(namebuf, localpkg)
+       symname := fmt.Sprintf(".gobytes.%d", slicebytes_gen)
+       sym := Pkglookup(symname, localpkg)
        sym.Def = newname(sym)
 
        off := 0
 
 func makefuncdatasym(namefmt string, funcdatakind int64) *Sym {
        var nod Node
 
-       namebuf = fmt.Sprintf(namefmt, makefuncdatasym_nsym)
+       sym := Lookupf(namefmt, makefuncdatasym_nsym)
        makefuncdatasym_nsym++
-       sym := Lookup(namebuf)
        pnod := newname(sym)
        pnod.Class = PEXTERN
        Nodconst(&nod, Types[TINT32], funcdatakind)
 
  * part of the composite literal.
  */
 func staticname(t *Type, ctxt int) *Node {
-       namebuf = fmt.Sprintf("statictmp_%.4d", statuniqgen)
+       n := newname(Lookupf("statictmp_%.4d", statuniqgen))
        statuniqgen++
-       n := newname(Lookup(namebuf))
        if ctxt == 0 {
                n.Readonly = true
        }
 
        return localpkg.Lookup(name)
 }
 
+func Lookupf(format string, a ...interface{}) *Sym {
+       return Lookup(fmt.Sprintf(format, a...))
+}
+
 func LookupBytes(name []byte) *Sym {
        return localpkg.LookupBytes(name)
 }
 
                        if Widthreg >= 8 || (et != TUINT64 && et != TINT64) {
                                goto ret
                        }
+                       var fn string
                        if et == TINT64 {
-                               namebuf = "int64"
+                               fn = "int64"
                        } else {
-                               namebuf = "uint64"
+                               fn = "uint64"
                        }
                        if n.Op == ODIV {
-                               namebuf += "div"
+                               fn += "div"
                        } else {
-                               namebuf += "mod"
+                               fn += "mod"
                        }
-                       n = mkcall(namebuf, n.Type, init, conv(n.Left, Types[et]), conv(n.Right, Types[et]))
+                       n = mkcall(fn, n.Type, init, conv(n.Left, Types[et]), conv(n.Right, Types[et]))
 
                default:
                        break
                args = list(args, conv(l.N, Types[TSTRING]))
        }
 
+       var fn string
        if c <= 5 {
                // small numbers of strings use direct runtime helpers.
                // note: orderexpr knows this cutoff too.
-               namebuf = fmt.Sprintf("concatstring%d", c)
+               fn = fmt.Sprintf("concatstring%d", c)
        } else {
                // large numbers of strings are passed to the runtime as a slice.
-               namebuf = "concatstrings"
+               fn = "concatstrings"
 
                t := typ(TARRAY)
                t.Type = Types[TSTRING]
                slice.Esc = EscNone
        }
 
-       cat := syslook(namebuf, 1)
+       cat := syslook(fn, 1)
        r := Nod(OCALL, cat, nil)
        r.List = args
        typecheck(&r, Erv)