diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index ce73018b8b0..af3e1ccbe4e 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -3219,6 +3219,11 @@ func walkcompare(np **Node, init **NodeList) { if l != nil { x := temp(r.Type) + if haspointers(r.Type) { + a := Nod(OAS, x, nil) + typecheck(&a, Etop) + *init = list(*init, a) + } ok := temp(Types[TBOOL]) // l.(type(r)) diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go index 16d54765b7e..f14dc30a7f1 100644 --- a/src/runtime/export_test.go +++ b/src/runtime/export_test.go @@ -154,3 +154,4 @@ func BenchSetType(n int, x interface{}) { const PtrSize = ptrSize var TestingAssertE2I2GC = &testingAssertE2I2GC +var TestingAssertE2T2GC = &testingAssertE2T2GC diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go index 636e5248c8b..6c9b314c65e 100644 --- a/src/runtime/gc_test.go +++ b/src/runtime/gc_test.go @@ -469,3 +469,20 @@ func testAssertVar(x interface{}) error { } return nil } + +func TestAssertE2T2Liveness(t *testing.T) { + *runtime.TestingAssertE2T2GC = true + defer func() { + *runtime.TestingAssertE2T2GC = false + }() + + poisonStack() + testIfaceEqual(io.EOF) +} + +func testIfaceEqual(x interface{}) { + if x == "abc" { + // Prevent inlining + panic("") + } +} diff --git a/src/runtime/iface.go b/src/runtime/iface.go index abd7068ed1a..332b7d50ab3 100644 --- a/src/runtime/iface.go +++ b/src/runtime/iface.go @@ -229,8 +229,13 @@ func assertE2T(t *_type, e interface{}, r unsafe.Pointer) { } } +var testingAssertE2T2GC bool + // The compiler ensures that r is non-nil. func assertE2T2(t *_type, e interface{}, r unsafe.Pointer) bool { + if testingAssertE2T2GC { + GC() + } ep := (*eface)(unsafe.Pointer(&e)) if ep._type != t { memclr(r, uintptr(t.size))