Source file test/fixedbugs/issue57823.go

     1  // run
     2  
     3  // Copyright 2023 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  package main
     8  
     9  import (
    10  	"runtime"
    11  	"unsafe"
    12  )
    13  
    14  //go:noinline
    15  func g(x *byte) *byte { return x }
    16  
    17  func main() {
    18  	slice()
    19  	str("AAAAAAAA", "BBBBBBBBB")
    20  }
    21  
    22  func wait(done <-chan struct{}) bool {
    23  	for i := 0; i < 10; i++ {
    24  		runtime.GC()
    25  		select {
    26  		case <-done:
    27  			return true
    28  		default:
    29  		}
    30  	}
    31  	return false
    32  }
    33  
    34  func slice() {
    35  	s := make([]byte, 100)
    36  	s[0] = 1
    37  	one := unsafe.SliceData(s)
    38  
    39  	done := make(chan struct{})
    40  	runtime.SetFinalizer(one, func(*byte) { close(done) })
    41  
    42  	h := g(one)
    43  
    44  	if wait(done) {
    45  		panic("GC'd early")
    46  	}
    47  
    48  	if *h != 1 {
    49  		panic("lost one")
    50  	}
    51  
    52  	if !wait(done) {
    53  		panic("never GC'd")
    54  	}
    55  }
    56  
    57  var strDone = make(chan struct{})
    58  
    59  //go:noinline
    60  func str(x, y string) {
    61  	s := x + y // put in temporary on stack
    62  	p := unsafe.StringData(s)
    63  	runtime.SetFinalizer(p, func(*byte) { close(strDone) })
    64  
    65  	if wait(strDone) {
    66  		panic("GC'd early")
    67  	}
    68  
    69  	if *p != 'A' {
    70  		panic("lost p")
    71  	}
    72  
    73  	if !wait(strDone) {
    74  		panic("never GC'd")
    75  	}
    76  }
    77  

View as plain text