Files
gasm-sdk/lint/corpus_test.go
2026-09-26 11:08:43 +02:00

66 lines
2.1 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
package lint
import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"sourcedock.dev/petrbalvin/gasm-sdk/arch"
"sourcedock.dev/petrbalvin/gasm-sdk/parser"
)
// TestGoRuntimeCorpus parses and lints every runtime .s file the local Go
// toolchain ships for all four supported architectures. This is the
// real-world regression net: it exercises the full breadth of each
// architecture's syntax (macros, addressing modes, branch aliases) against
// production assembly. It is skipped when the toolchain source is absent.
//
// The bar is zero parse errors and zero error-severity diagnostics; i.e. no
// false "unknown instruction" / "undefined label" findings on code the real
// assembler accepts. Advisory warnings are reported but not fatal, since they
// are heuristics that may legitimately differ across Go versions.
func TestGoRuntimeCorpus(t *testing.T) {
out, err := exec.Command("go", "env", "GOROOT").Output()
if err != nil {
t.Skipf("cannot locate GOROOT: %v", err)
}
dir := filepath.Join(strings.TrimSpace(string(out)), "src", "runtime")
var files []string
for _, suffix := range []string{"_amd64.s", "_arm64.s", "_riscv64.s", "_loong64.s"} {
matches, _ := filepath.Glob(filepath.Join(dir, "*"+suffix))
files = append(files, matches...)
}
if len(files) == 0 {
t.Skip("Go toolchain source (src/runtime/*.s) not present")
}
warnings := 0
for _, path := range files {
src, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read %s: %v", path, err)
}
f, errs := parser.Parse(path, string(src))
if len(errs) > 0 {
t.Errorf("parse %s: %v", filepath.Base(path), errs)
continue
}
diags := File(f, Config{Arch: arch.FromFilename(path)})
for _, d := range diags {
if d.Severity == Error {
t.Errorf("%s:%d: error %s: %s", filepath.Base(path), d.Pos.Line, d.Code, d.Message)
} else {
warnings++
}
}
}
if warnings > 0 {
t.Logf("%d advisory warnings across %d files (non-fatal)", warnings, len(files))
}
}