func DeclaredInMain() {
}
+type C struct {
+}
+
+func F() *C {
+ return nil
+}
+
func main() {
defer depBase.ImplementedInAsm()
// This code below causes various go.itab.* symbols to be generated in
reflect.TypeOf(os.Stdout).Elem()
runtime.GC()
depBase.V = depBase.F() + 1
+
+ var c *C
+ if reflect.TypeOf(F).Out(0) != reflect.TypeOf(c) {
+ panic("bad reflection results, see golang.org/issue/18252")
+ }
}
Fatalf("itabname(%v, %v)", t, itype)
}
s := Pkglookup(t.tconv(FmtLeft)+","+itype.tconv(FmtLeft), itabpkg)
- Linksym(s).Set(obj.AttrLocal, true)
if s.Def == nil {
n := newname(s)
n.Type = Types[TUINT8]
// }
o := dsymptr(i.sym, 0, dtypesym(i.itype), 0)
o = dsymptr(i.sym, o, dtypesym(i.t), 0)
- o += Widthptr + 8 // skip link/bad/unused fields
+ o += Widthptr + 8 // skip link/bad/inhash fields
o += len(imethods(i.itype)) * Widthptr // skip fun method pointers
// at runtime the itab will contain pointers to types, other itabs and
// method functions. None are allocated on heap, so we can use obj.NOPTR.
- ggloblsym(i.sym, int32(o), int16(obj.DUPOK|obj.NOPTR|obj.LOCAL))
+ ggloblsym(i.sym, int32(o), int16(obj.DUPOK|obj.NOPTR))
ilink := Pkglookup(i.t.tconv(FmtLeft)+","+i.itype.tconv(FmtLeft), itablinkpkg)
dsymptr(ilink, 0, i.sym, 0)
- ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA|obj.LOCAL))
+ ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
}
// process ptabs
throw("invalid itab locking")
}
h := itabhash(inter, typ)
- if m == hash[h] {
- println("duplicate itab for", typ.string(), "and", inter.typ.string())
- throw("duplicate itabs")
- }
m.link = hash[h]
+ m.inhash = 1
atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))
}
lock(&ifaceLock)
for _, md := range activeModules() {
for _, i := range md.itablinks {
- additab(i, true, false)
+ // itablinks is a slice of pointers to the itabs used in this
+ // module. A given itab may be used in more than one module
+ // and thanks to the way global symbol resolution works, the
+ // pointed-to itab may already have been inserted into the
+ // global 'hash'.
+ if i.inhash == 0 {
+ additab(i, true, false)
+ }
}
}
unlock(&ifaceLock)