runtime: clear Defer.fn before removing from the G.defer list

Should fix the remaining 'invalid heap pointer' build failures.

TBR=khr
CC=golang-codereviews
https://golang.org/cl/152360043
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 58b14b0..685ff5c 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -191,6 +191,9 @@
 	if d._panic != nil {
 		freedeferpanic()
 	}
+	if d.fn != nil {
+		freedeferfn()
+	}
 	sc := deferclass(uintptr(d.siz))
 	if sc < uintptr(len(p{}.deferpool)) {
 		mp := acquirem()
@@ -209,6 +212,11 @@
 	gothrow("freedefer with d._panic != nil")
 }
 
+func freedeferfn() {
+	// fn must be cleared before d is unlinked from gp.
+	gothrow("freedefer with d.fn != nil")
+}
+
 // Run a deferred function if there is one.
 // The compiler inserts a call to this at the end of any
 // function which calls defer.
@@ -241,6 +249,7 @@
 	mp := acquirem()
 	memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
 	fn := d.fn
+	d.fn = nil
 	gp._defer = d.link
 	freedefer(d)
 	releasem(mp)
@@ -270,6 +279,7 @@
 				d._panic.aborted = true
 				d._panic = nil
 			}
+			d.fn = nil
 			gp._defer = d.link
 			freedefer(d)
 			continue
@@ -280,6 +290,7 @@
 			gothrow("bad defer entry in Goexit")
 		}
 		d._panic = nil
+		d.fn = nil
 		gp._defer = d.link
 		freedefer(d)
 		// Note: we ignore recovers here because Goexit isn't a panic
@@ -356,6 +367,7 @@
 				d._panic.aborted = true
 			}
 			d._panic = nil
+			d.fn = nil
 			gp._defer = d.link
 			freedefer(d)
 			continue
@@ -380,6 +392,7 @@
 			gothrow("bad defer entry in panic")
 		}
 		d._panic = nil
+		d.fn = nil
 		gp._defer = d.link
 
 		// trigger shrinkage to test stack copy.  See stack_test.go:TestStackPanic