// Copyright (c) 2026 Petr Balvín (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) } } }