Home | History | Annotate | Download | only in fixedbugs
      1 // run
      2 
      3 // Copyright 2017 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      6 
      7 // Issue 19078: liveness & zero-initialization of results
      8 // when there is a defer.
      9 package main
     10 
     11 import "unsafe"
     12 
     13 func main() {
     14 	// Construct an invalid pointer.  We do this by
     15 	// making a pointer which points to the unused space
     16 	// between the last 48-byte object in a span and the
     17 	// end of the span (there are 32 unused bytes there).
     18 	p := new([48]byte)              // make a 48-byte object
     19 	sink = &p                       // escape it, so it allocates for real
     20 	u := uintptr(unsafe.Pointer(p)) // get its address
     21 	u = u >> 13 << 13               // round down to page size
     22 	u += 1<<13 - 1                  // add almost a page
     23 
     24 	for i := 0; i < 1000000; i++ {
     25 		_ = identity(u)         // installs u at return slot
     26 		_ = liveReturnSlot(nil) // incorrectly marks return slot as live
     27 	}
     28 }
     29 
     30 //go:noinline
     31 func liveReturnSlot(x *int) *int {
     32 	defer func() {}() // causes return slot to be marked live
     33 	sink = &x         // causes x to be moved to the heap, triggering allocation
     34 	return x
     35 }
     36 
     37 //go:noinline
     38 func identity(x uintptr) uintptr {
     39 	return x
     40 }
     41 
     42 var sink interface{}
     43