| // run |
| |
| // Copyright 2025 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 "runtime" |
| |
| const C = 16 |
| |
| type T [C * C]byte |
| |
| func main() { |
| var ts []*T |
| |
| for i := 0; i < 100; i++ { |
| t := new(T) |
| // Save every even object. |
| if i%2 == 0 { |
| ts = append(ts, t) |
| } |
| } |
| // Make sure the odd objects are collected. |
| runtime.GC() |
| |
| for _, t := range ts { |
| f(t, C, C) |
| } |
| } |
| |
| //go:noinline |
| func f(t *T, i, j uint) { |
| if i == 0 || i > C || j == 0 || j > C { |
| return // gets rid of bounds check below (via prove pass) |
| } |
| p := &t[i*j-1] |
| *p = 0 |
| runtime.GC() |
| *p = 0 |
| |
| // This goes badly if compiled to |
| // q := &t[i*j] |
| // *(q-1) = 0 |
| // runtime.GC() |
| // *(q-1) = 0 |
| // as at the GC call, q is an invalid pointer |
| // (it points past the end of t's allocation). |
| } |