diff options
Diffstat (limited to 'test/fixedbugs/issue4909b.go')
-rw-r--r-- | test/fixedbugs/issue4909b.go | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/test/fixedbugs/issue4909b.go b/test/fixedbugs/issue4909b.go new file mode 100644 index 0000000..7d79227 --- /dev/null +++ b/test/fixedbugs/issue4909b.go @@ -0,0 +1,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") + } +} |