0
1
mirror of https://github.com/golang/go synced 2024-11-11 12:49:30 +00:00
go/test/fixedbugs/issue55122.go
Keith Randall e283473ebb cmd/compile: avoid using destination pointer base type in memmove optimization
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>
2022-09-19 18:21:06 +00:00

43 lines
627 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 *[]byte:
*e = nil
}
}
var sink []byte