/
githubmirror
/
go
Обзор
Документация
Войти
/
githubmirror
/
go
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
test/fixedbugs/issue62469.go
80 строк
2 KB
Josh Bleecher Snyder
cmd/compile: prevent arm[64] noov InvertFlags miscompilation at min int
15 июл 2026, 21:45
15 июл 2026, 21:45
607cfce
Код
Авторство
О чём код?
// run // Copyright 2023 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. // Comparing a wrapped product difference against zero must respect the // sign of the wrapped value, even when it wraps to MinInt. package main import "fmt" // int64 (not int) so the cross product is 64-bit on every GOARCH. type point struct{ x, y int64 } //go:noinline func sign(p1, p2, p3 point) bool { return (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y) < 0 } type point32 struct{ x, y int32 } //go:noinline func sign32(p1, p2, p3 point32) bool { if (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y) < 0 { return true } return false } const minInt64 = -1 << 63 //go:noinline func msub64(x, y int64) bool { if minInt64-x*y < 0 { return true } return false } const minInt32 = -1 << 31 //go:noinline func msub32(x, y int32) bool { if minInt32-x*y < 0 { return true } return false } const minUint32 = uint32(1 << 31) //go:noinline func umod32(y uint32) bool { if int32(minUint32%y) < 0 { return true } return false } func main() { var bad bool check := func(name string, got, want bool) { if got != want { fmt.Printf("%s = %v, want %v\n", name, got, want) bad = true } } check("sign", sign(point{0, 2}, point{1 << 62, 0}, point{0, 0}), true) // wraps to MinInt64 check("sign32", sign32(point32{0, 2}, point32{1 << 30, 0}, point32{0, 0}), true) // wraps to MinInt32 check("msub64", msub64(0, 123), true) // minInt64 - 0 check("msub32", msub32(0, 123), true) // minInt32 - 0 check("umod32", umod32(0xffffffff), true) // minUint32 % big == minUint32 if bad { panic("InvertFlags noov MinInt miscompilation") } }