mirror of
https://github.com/golang/go
synced 2024-11-26 17:16:54 -07:00
e283473ebb
The type of the source and destination of a memmove call isn't always accurate. It will always be a pointer (or an unsafe.Pointer), but the base type might not be accurate. This comes about because multiple copies of a pointer with different base types are coalesced into a single value. In the failing example, the IData selector of the input argument is a *[32]byte in one branch of the type switch, and a *[]byte in the other branch. During the expand_calls pass both IDatas become just copies of the input register. Those copies are deduped and an arbitrary one wins (in this case, *[]byte is the unfortunate winner). Generally an op v can rely on v.Type during rewrite rules. But relying on v.Args[i].Type is discouraged. Fixes #55122 Change-Id: I348fd9accf2058a87cd191eec01d39cda612f120 Reviewed-on: https://go-review.googlesource.com/c/go/+/431496 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@google.com>
44 lines
644 B
Go
44 lines
644 B
Go
// run
|
|
|
|
// Copyright 2022 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
|
|
|
|
func main() {
|
|
for i := 0; i < 10000; i++ {
|
|
h(i)
|
|
sink = make([]byte, 1024) // generate some garbage
|
|
}
|
|
}
|
|
|
|
func h(iter int) {
|
|
var x [32]byte
|
|
for i := 0; i < 32; i++ {
|
|
x[i] = 99
|
|
}
|
|
g(&x)
|
|
if x == ([32]byte{}) {
|
|
return
|
|
}
|
|
for i := 0; i < 32; i++ {
|
|
println(x[i])
|
|
}
|
|
panic(iter)
|
|
}
|
|
|
|
//go:noinline
|
|
func g(x interface{}) {
|
|
switch e := x.(type) {
|
|
case *[32]byte:
|
|
var c [32]byte
|
|
*e = c
|
|
case *[3]*byte:
|
|
var c [3]*byte
|
|
*e = c
|
|
}
|
|
}
|
|
|
|
var sink []byte
|