// 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")
}
}