Initial commit: Go 1.23 release state
This commit is contained in:
104
test/fixedbugs/issue16095.go
Normal file
104
test/fixedbugs/issue16095.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// run
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
var sink *[20]byte
|
||||
|
||||
func f() (x [20]byte) {
|
||||
// Initialize x.
|
||||
for i := range x {
|
||||
x[i] = byte(i)
|
||||
}
|
||||
|
||||
// Force x to be allocated on the heap.
|
||||
sink = &x
|
||||
sink = nil
|
||||
|
||||
// Go to deferreturn after the panic below.
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
|
||||
// This call collects the heap-allocated version of x (oops!)
|
||||
runtime.GC()
|
||||
|
||||
// Allocate that same object again and clobber it.
|
||||
y := new([20]byte)
|
||||
for i := 0; i < 20; i++ {
|
||||
y[i] = 99
|
||||
}
|
||||
// Make sure y is heap allocated.
|
||||
sink = y
|
||||
|
||||
panic(nil)
|
||||
|
||||
// After the recover we reach the deferreturn, which
|
||||
// copies the heap version of x back to the stack.
|
||||
// It gets the pointer to x from a stack slot that was
|
||||
// not marked as live during the call to runtime.GC().
|
||||
}
|
||||
|
||||
var sinkint int
|
||||
|
||||
func g(p *int) (x [20]byte) {
|
||||
// Initialize x.
|
||||
for i := range x {
|
||||
x[i] = byte(i)
|
||||
}
|
||||
|
||||
// Force x to be allocated on the heap.
|
||||
sink = &x
|
||||
sink = nil
|
||||
|
||||
// Go to deferreturn after the panic below.
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
|
||||
// This call collects the heap-allocated version of x (oops!)
|
||||
runtime.GC()
|
||||
|
||||
// Allocate that same object again and clobber it.
|
||||
y := new([20]byte)
|
||||
for i := 0; i < 20; i++ {
|
||||
y[i] = 99
|
||||
}
|
||||
// Make sure y is heap allocated.
|
||||
sink = y
|
||||
|
||||
// panic with a non-call (with no fallthrough)
|
||||
for {
|
||||
sinkint = *p
|
||||
}
|
||||
|
||||
// After the recover we reach the deferreturn, which
|
||||
// copies the heap version of x back to the stack.
|
||||
// It gets the pointer to x from a stack slot that was
|
||||
// not marked as live during the call to runtime.GC().
|
||||
}
|
||||
|
||||
func main() {
|
||||
x := f()
|
||||
for i, v := range x {
|
||||
if v != byte(i) {
|
||||
fmt.Printf("%v\n", x)
|
||||
panic("bad f")
|
||||
}
|
||||
}
|
||||
x = g(nil)
|
||||
for i, v := range x {
|
||||
if v != byte(i) {
|
||||
fmt.Printf("%v\n", x)
|
||||
panic("bad g")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user