1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// 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|embedded via a pointer"`)
}
fmt.Print("\n")
}
}
|