Source file test/fixedbugs/issue27695c.go

     1  // run
     2  
     3  // Copyright 2018 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  // Make sure return values aren't scanned until they
     8  // are initialized, when calling functions and methods
     9  // via reflect.
    10  
    11  package main
    12  
    13  import (
    14  	"io"
    15  	"reflect"
    16  	"runtime"
    17  	"unsafe"
    18  )
    19  
    20  var badPtr uintptr
    21  
    22  var sink []byte
    23  
    24  func init() {
    25  	// Allocate large enough to use largeAlloc.
    26  	b := make([]byte, 1<<16-1)
    27  	sink = b // force heap allocation
    28  	//  Any space between the object and the end of page is invalid to point to.
    29  	badPtr = uintptr(unsafe.Pointer(&b[len(b)-1])) + 1
    30  }
    31  
    32  func f(d func(error) error) error {
    33  	// Initialize callee args section with a bad pointer.
    34  	g(badPtr, badPtr, badPtr, badPtr)
    35  
    36  	// Then call a function which returns a pointer.
    37  	// That return slot starts out holding a bad pointer.
    38  	return d(io.EOF)
    39  }
    40  
    41  //go:noinline
    42  func g(x, y, z, w uintptr) {
    43  }
    44  
    45  type T struct {
    46  }
    47  
    48  func (t *T) Foo(e error) error {
    49  	runtime.GC()
    50  	return e
    51  }
    52  
    53  func main() {
    54  	// Functions
    55  	d := reflect.MakeFunc(reflect.TypeOf(func(e error) error { return e }),
    56  		func(args []reflect.Value) []reflect.Value {
    57  			runtime.GC()
    58  			return args
    59  		}).Interface().(func(error) error)
    60  	f(d)
    61  
    62  	// Methods
    63  	x := reflect.ValueOf(&T{}).Method(0).Interface().(func(error) error)
    64  	f(x)
    65  }
    66  

View as plain text