/
githubmirror
/
go
Обзор
Документация
Войти
/
githubmirror
/
go
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/fixedbugs/issue80519.go
136 строк
3 KB
Darren Carreras
cmd/compile: avoid range clear when target depends on index
03 авг 2026, 08:07
03 авг 2026, 08:07
505c369
Код
Авторство
О чём код?
// run // Copyright 2026 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" "unsafe" ) var aliased = [3][3]int{{9, 9, 9}, {1, 9, 9}, {9, 9, 9}} var unsafeAliased [3]unsafe.Pointer type unsafeFieldTarget struct { array *[4]uintptr pad [3]uintptr } //go:noinline func clearAliased() { keyp := &aliased[1][0] for i := range 3 { aliased[*keyp][i] = 0 } } //go:noinline func clearUnsafeAliased() { target := (*[3]unsafe.Pointer)(unsafe.Pointer(&unsafeAliased[0])) unsafeAliased[0] = unsafe.Pointer(target) targetp := (**[3]unsafe.Pointer)(unsafe.Pointer(&unsafeAliased[0])) for i := range 3 { (**targetp)[i] = nil } } //go:noinline func clearUnsafeField(t *unsafeFieldTarget) { for i := range t.array { t.array[i] = 0 } } //go:noinline func clearUnsafeSlice() { var values []uintptr values = unsafe.Slice((*uintptr)(unsafe.Pointer(&values)), 3) for i := range values { values[i] = 0 } } func main() { want := [3][2]int{{0, 2}, {3, 0}, {5, 6}} rows := [3][2]int{{1, 2}, {3, 4}, {5, 6}} key := 2 for key = range 2 { rows[key][key] = 0 } if rows != want || key != 1 { panic("range clear with assigned index variable") } rows = [3][2]int{{1, 2}, {3, 4}, {5, 6}} for key := range 2 { rows[key][key] = 0 } if rows != want { panic("range clear with declared index variable") } slices := [3][]int{{1, 2}, {3, 4}, {5, 6}} key = 0 for key = range slices[key] { slices[key][key] = 0 } if slices[0][0] != 0 || slices[0][1] != 2 || slices[1][0] != 3 || slices[1][1] != 0 || key != 1 { panic("range clear with index-dependent slice") } rows = [3][2]int{{1, 2}, {3, 4}, {5, 6}} key = 0 keyp := &key for key = range 2 { rows[*keyp][key] = 0 } if rows != want || key != 1 { panic("range clear with indirect index dependency") } clearAliased() if aliased != [3][3]int{{9, 0, 0}, {0, 9, 9}, {9, 9, 9}} { panic("range clear target changed through cleared memory") } panicked := false func() { defer func() { panicked = recover() != nil }() clearUnsafeAliased() }() if !panicked { panic("range clear target changed through unsafe pointer") } fieldTarget := unsafeFieldTarget{} fieldTarget.array = (*[4]uintptr)(unsafe.Pointer(&fieldTarget)) panicked = false func() { defer func() { panicked = recover() != nil }() clearUnsafeField(&fieldTarget) }() if !panicked { panic("range clear target changed through unsafe pointer field") } if runtime.GOARCH != "wasm" { panicked = false func() { defer func() { panicked = recover() != nil }() clearUnsafeSlice() }() if !panicked { panic("range clear target changed through unsafe slice header") } } }