Source file test/fixedbugs/issue24491a.go

     1  // run
     2  
     3  // Copyright 2020 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  // This test makes sure unsafe-uintptr arguments are handled correctly.
     8  
     9  package main
    10  
    11  import (
    12  	"runtime"
    13  	"unsafe"
    14  )
    15  
    16  var done = make(chan bool, 1)
    17  
    18  func setup() unsafe.Pointer {
    19  	s := "ok"
    20  	runtime.SetFinalizer(&s, func(p *string) { *p = "FAIL" })
    21  	return unsafe.Pointer(&s)
    22  }
    23  
    24  //go:noinline
    25  //go:uintptrescapes
    26  func test(s string, p, q uintptr, rest ...uintptr) int {
    27  	runtime.GC()
    28  	runtime.GC()
    29  
    30  	if *(*string)(unsafe.Pointer(p)) != "ok" {
    31  		panic(s + ": p failed")
    32  	}
    33  	if *(*string)(unsafe.Pointer(q)) != "ok" {
    34  		panic(s + ": q failed")
    35  	}
    36  	for _, r := range rest {
    37  		if *(*string)(unsafe.Pointer(r)) != "ok" {
    38  			panic(s + ": r[i] failed")
    39  		}
    40  	}
    41  
    42  	done <- true
    43  	return 0
    44  }
    45  
    46  //go:noinline
    47  func f() int {
    48  	return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    49  }
    50  
    51  type S struct{}
    52  
    53  //go:noinline
    54  //go:uintptrescapes
    55  func (S) test(s string, p, q uintptr, rest ...uintptr) int {
    56  	return test(s, p, q, rest...)
    57  }
    58  
    59  func main() {
    60  	test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    61  	<-done
    62  
    63  	go test("go", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    64  	<-done
    65  
    66  	func() {
    67  		defer test("defer", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    68  	}()
    69  	<-done
    70  
    71  	func() {
    72  		for {
    73  			defer test("defer in for loop", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    74  			break
    75  		}
    76  	}()
    77  	<-done
    78  
    79  	func() {
    80  		s := &S{}
    81  		defer s.test("method call", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    82  	}()
    83  	<-done
    84  
    85  	func() {
    86  		s := &S{}
    87  		for {
    88  			defer s.test("defer method loop", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
    89  			break
    90  		}
    91  	}()
    92  	<-done
    93  
    94  	f()
    95  	<-done
    96  }
    97  

View as plain text