tests: autogenerated test to confirm attribute strings

Test helps verify our attribute types match the macros in textflag.h.
Discovered https://golang.org/issue/29487 in the process.

Updates #2
This commit is contained in:
Michael McLoughlin
2018-12-31 17:30:03 -08:00
parent 6d6ff3cfc1
commit f2315d539c
5 changed files with 1657 additions and 11 deletions

20
attr.go
View File

@@ -83,14 +83,14 @@ func (a Attribute) split() ([]string, Attribute) {
}
var attrname = map[Attribute]string{
NOPROF: "NOPROF",
DUPOK: "DUPOK",
NOSPLIT: "NOSPLIT",
RODATA: "RODATA",
NOPTR: "NOPTR",
WRAPPER: "WRAPPER",
NEEDCTXT: "NEEDCTXT",
TLSBSS: "TLSBSS",
NOFRAME: "NOFRAME",
REFLECTMETHOD: "REFLECTMETHOD",
NOPROF: "NOPROF",
DUPOK: "DUPOK",
NOSPLIT: "NOSPLIT",
RODATA: "RODATA",
NOPTR: "NOPTR",
WRAPPER: "WRAPPER",
NEEDCTXT: "NEEDCTXT",
TLSBSS: "TLSBSS",
NOFRAME: "NOFRAME",
// REFLECTMETHOD excluded due to https://golang.org/issue/29487
}

View File

@@ -13,7 +13,8 @@ func TestAttributeAsm(t *testing.T) {
{DUPOK, "DUPOK"},
{RODATA | NOSPLIT, "NOSPLIT|RODATA"},
{WRAPPER | 16384 | NOPTR, "NOPTR|WRAPPER|16384"},
{NEEDCTXT + NOFRAME + TLSBSS + REFLECTMETHOD, "NEEDCTXT|TLSBSS|NOFRAME|REFLECTMETHOD"},
{NEEDCTXT + NOFRAME + TLSBSS, "NEEDCTXT|TLSBSS|NOFRAME"},
{REFLECTMETHOD, "1024"}, // REFLECTMETHOD special case due to https://golang.org/issue/29487
}
for _, c := range cases {
got := c.Attribute.Asm()

View File

@@ -0,0 +1,13 @@
package textflag
import "testing"
//go:generate go run make_attrtest.go -output zattrtest.s -seed 42 -num 256
func AttrTest() bool
func TestAttributes(t *testing.T) {
if !AttrTest() {
t.Fail()
}
}

View File

@@ -0,0 +1,88 @@
// +build ignore
package main
import (
"bytes"
"flag"
"fmt"
"io"
"log"
"math/rand"
"os"
"path/filepath"
"runtime"
"github.com/mmcloughlin/avo"
)
var (
output = flag.String("output", "", "path to output file (default stdout)")
seed = flag.Int64("seed", 0, "random seed")
num = flag.Int("num", 32, "number of attributes to generate")
)
func GenerateAttributes(n int) []avo.Attribute {
as := make([]avo.Attribute, 0, n)
// Include each bitlevel.
for i := 0; i < 16 && i < n; i++ {
a := avo.Attribute(1 << uint(i))
as = append(as, a)
}
// Add randomly generated attributes.
for len(as) < n {
a := avo.Attribute(rand.Uint32())
as = append(as, a)
}
return as
}
func PrintAttributesTest(w io.Writer, as []avo.Attribute) {
_, self, _, _ := runtime.Caller(0)
fmt.Fprintf(w, "// Code generated by %s. DO NOT EDIT.\n\n", filepath.Base(self))
fmt.Fprintf(w, "#include \"textflag.h\"\n\n")
fmt.Fprintf(w, "TEXT ·AttrTest(SB), $0-1\n")
fmt.Fprintf(w, "\tMOVB $0, ret+0(FP)\n")
for i, a := range as {
fmt.Fprintf(w, "\tMOVW $(%d), R8\n", a)
fmt.Fprintf(w, "\tMOVW $(%s), R9\n", a.Asm())
fmt.Fprintf(w, "\tCMPW R8, R9\n")
cont := fmt.Sprintf("cont%d", i)
fmt.Fprintf(w, "\tJE %s\n", cont)
fmt.Fprintf(w, "\tRET\n")
fmt.Fprintf(w, "%s:\n", cont)
}
fmt.Fprintf(w, "\tMOVB $1, ret+0(FP)\n")
fmt.Fprintf(w, "\tRET\n")
}
func main() {
flag.Parse()
w := os.Stdout
if *output != "" {
f, err := os.Create(*output)
if err != nil {
log.Fatal(err)
}
defer f.Close()
w = f
}
rand.Seed(*seed)
as := GenerateAttributes(*num)
buf := bytes.NewBuffer(nil)
PrintAttributesTest(buf, as)
if _, err := w.Write(buf.Bytes()); err != nil {
log.Fatal(err)
}
}

1544
tests/textflag/zattrtest.s Normal file

File diff suppressed because it is too large Load Diff