mirror of
https://github.com/golang/go
synced 2024-09-05 07:54:46 +00:00
![Rémy Oudompheng](/assets/img/avatar_default.png)
The offset of an embedded field s.X must be relative to s and not to the implicit s.Field of which X is a direct field. Moreover, no indirections may happen on the path. Fixes #4909. R=nigeltao, ality, daniel.morsing, iant, gri, r CC=golang-dev https://golang.org/cl/8287043
81 lines
1.3 KiB
Go
81 lines
1.3 KiB
Go
// errorcheckoutput
|
|
|
|
package main
|
|
|
|
import "fmt"
|
|
|
|
// We are going to define 256 types T(n),
|
|
// such that T(n) embeds T(2n) and *T(2n+1).
|
|
|
|
func main() {
|
|
fmt.Printf("// errorcheck\n\n")
|
|
fmt.Printf("package p\n\n")
|
|
fmt.Println(`import "unsafe"`)
|
|
|
|
// Dump types.
|
|
for n := 1; n < 256; n++ {
|
|
writeStruct(n)
|
|
}
|
|
// Dump leaves
|
|
for n := 256; n < 512; n++ {
|
|
fmt.Printf("type T%d int\n", n)
|
|
}
|
|
|
|
fmt.Printf("var t T1\n")
|
|
fmt.Printf("var p *T1\n")
|
|
|
|
// Simple selectors
|
|
for n := 2; n < 256; n++ {
|
|
writeDot(n)
|
|
}
|
|
|
|
// Double selectors
|
|
for n := 128; n < 256; n++ {
|
|
writeDot(n/16, n)
|
|
}
|
|
|
|
// Triple selectors
|
|
for n := 128; n < 256; n++ {
|
|
writeDot(n/64, n/8, n)
|
|
}
|
|
}
|
|
|
|
const structTpl = `
|
|
type T%d struct {
|
|
A%d int
|
|
T%d
|
|
*T%d
|
|
}
|
|
`
|
|
|
|
func writeStruct(n int) {
|
|
fmt.Printf(structTpl, n, n, 2*n, 2*n+1)
|
|
}
|
|
|
|
func writeDot(ns ...int) {
|
|
for _, root := range []string{"t", "p"} {
|
|
fmt.Printf("const _ = unsafe.Offsetof(%s", root)
|
|
for _, n := range ns {
|
|
fmt.Printf(".T%d", n)
|
|
}
|
|
// Does it involve an indirection?
|
|
nlast := ns[len(ns)-1]
|
|
nprev := 1
|
|
if len(ns) > 1 {
|
|
nprev = ns[len(ns)-2]
|
|
}
|
|
isIndirect := false
|
|
for n := nlast / 2; n > nprev; n /= 2 {
|
|
if n%2 == 1 {
|
|
isIndirect = true
|
|
break
|
|
}
|
|
}
|
|
fmt.Print(")")
|
|
if isIndirect {
|
|
fmt.Print(` // ERROR "indirection"`)
|
|
}
|
|
fmt.Print("\n")
|
|
}
|
|
}
|