65 lines
2.1 KiB
Go
65 lines
2.1 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package asm
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"sourcedock.dev/petrbalvin/gasm-sdk/parser"
|
|
)
|
|
|
|
// arm64AcceptedErrorShapes lists the toolchain's arm64error.s spellings gasm
|
|
// still accepts, each an acceptance superset with a known shape. The list
|
|
// only shrinks: every tightening of the encoder moves spellings out of it,
|
|
// and a spelling reappearing here means a regression. The catalogue is
|
|
// empty as of Go 1.27: every line the toolchain's corpus rejects, gasm
|
|
// rejects too.
|
|
var arm64AcceptedErrorShapes = []string{}
|
|
|
|
// TestArm64ToolchainErrorParity walks the toolchain's arm64error.s (Go
|
|
// 1.27, arm64) and requires gasm to reject every case the toolchain rejects.
|
|
// A live Go toolchain is needed for the source file; the test skips without
|
|
// one or in -short.
|
|
func TestArm64ToolchainErrorParity(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("live arm64error.s corpus: skipped in -short mode")
|
|
}
|
|
goroot := os.Getenv("GOROOT")
|
|
if goroot == "" {
|
|
t.Skip("no GOROOT")
|
|
}
|
|
path := filepath.Join(goroot, "src", "cmd", "asm", "internal", "asm", "testdata", "arm64error.s")
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Skip(err)
|
|
}
|
|
allowed := map[string]bool{}
|
|
for _, s := range arm64AcceptedErrorShapes {
|
|
allowed[s] = true
|
|
}
|
|
for raw := range strings.SplitSeq(string(data), "\n") {
|
|
line := strings.TrimSpace(raw)
|
|
if line == "" || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "TEXT") || !strings.Contains(line, "ERROR") {
|
|
continue
|
|
}
|
|
body := line
|
|
if i := strings.Index(body, "//"); i >= 0 {
|
|
body = strings.TrimSpace(body[:i])
|
|
}
|
|
body = strings.ReplaceAll(body, "\t", " ")
|
|
body = strings.Join(strings.Fields(body), " ")
|
|
src := "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n\t" + body + "\n\tRET\n"
|
|
f, perr := parser.Parse("errorparity.s", src)
|
|
if len(perr) > 0 {
|
|
continue // the parser already rejects the spelling
|
|
}
|
|
if _, aerr := AssembleFileARM64(f); aerr == nil && !allowed[body] {
|
|
t.Errorf("gasm accepts what the toolchain rejects: %s", body)
|
|
}
|
|
}
|
|
}
|