compiler: add tests for error messages
The test is currently empty, but will be used in the next commit.
Этот коммит содержится в:
родитель
6dba16f28e
коммит
41e787d504
2 изменённых файлов: 86 добавлений и 43 удалений
|
@ -70,52 +70,11 @@ func TestCompiler(t *testing.T) {
|
||||||
options := &compileopts.Options{
|
options := &compileopts.Options{
|
||||||
Target: targetString,
|
Target: targetString,
|
||||||
}
|
}
|
||||||
target, err := compileopts.LoadTarget(options)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to load target:", err)
|
|
||||||
}
|
|
||||||
if tc.scheduler != "" {
|
if tc.scheduler != "" {
|
||||||
options.Scheduler = tc.scheduler
|
options.Scheduler = tc.scheduler
|
||||||
}
|
}
|
||||||
config := &compileopts.Config{
|
|
||||||
Options: options,
|
|
||||||
Target: target,
|
|
||||||
}
|
|
||||||
compilerConfig := &Config{
|
|
||||||
Triple: config.Triple(),
|
|
||||||
Features: config.Features(),
|
|
||||||
ABI: config.ABI(),
|
|
||||||
GOOS: config.GOOS(),
|
|
||||||
GOARCH: config.GOARCH(),
|
|
||||||
CodeModel: config.CodeModel(),
|
|
||||||
RelocationModel: config.RelocationModel(),
|
|
||||||
Scheduler: config.Scheduler(),
|
|
||||||
AutomaticStackSize: config.AutomaticStackSize(),
|
|
||||||
DefaultStackSize: config.StackSize(),
|
|
||||||
NeedsStackObjects: config.NeedsStackObjects(),
|
|
||||||
}
|
|
||||||
machine, err := NewTargetMachine(compilerConfig)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to create target machine:", err)
|
|
||||||
}
|
|
||||||
defer machine.Dispose()
|
|
||||||
|
|
||||||
// Load entire program AST into memory.
|
mod, errs := testCompilePackage(t, options, tc.file)
|
||||||
lprogram, err := loader.Load(config, "./testdata/"+tc.file, config.ClangHeaders, types.Config{
|
|
||||||
Sizes: Sizes(machine),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal("failed to create target machine:", err)
|
|
||||||
}
|
|
||||||
err = lprogram.Parse()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("could not parse test case %s: %s", tc.file, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compile AST to IR.
|
|
||||||
program := lprogram.LoadSSA()
|
|
||||||
pkg := lprogram.MainPkg()
|
|
||||||
mod, errs := CompilePackage(tc.file, pkg, program.Package(pkg.Pkg), machine, compilerConfig, false)
|
|
||||||
if errs != nil {
|
if errs != nil {
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
@ -123,7 +82,7 @@ func TestCompiler(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = llvm.VerifyModule(mod, llvm.PrintMessageAction)
|
err := llvm.VerifyModule(mod, llvm.PrintMessageAction)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -216,3 +175,86 @@ func filterIrrelevantIRLines(lines []string) []string {
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompilerErrors(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// Read expected errors from the test file.
|
||||||
|
var expectedErrors []string
|
||||||
|
errorsFile, err := os.ReadFile("testdata/errors.go")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
errorsFileString := strings.ReplaceAll(string(errorsFile), "\r\n", "\n")
|
||||||
|
for _, line := range strings.Split(errorsFileString, "\n") {
|
||||||
|
if strings.HasPrefix(line, "// ERROR: ") {
|
||||||
|
expectedErrors = append(expectedErrors, strings.TrimPrefix(line, "// ERROR: "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile the Go file with errors.
|
||||||
|
options := &compileopts.Options{
|
||||||
|
Target: "wasm",
|
||||||
|
}
|
||||||
|
_, errs := testCompilePackage(t, options, "errors.go")
|
||||||
|
|
||||||
|
// Check whether the actual errors match the expected errors.
|
||||||
|
expectedErrorsIdx := 0
|
||||||
|
for _, err := range errs {
|
||||||
|
err := err.(types.Error)
|
||||||
|
position := err.Fset.Position(err.Pos)
|
||||||
|
position.Filename = "errors.go" // don't use a full path
|
||||||
|
if expectedErrorsIdx >= len(expectedErrors) || expectedErrors[expectedErrorsIdx] != err.Msg {
|
||||||
|
t.Errorf("unexpected compiler error: %s: %s", position.String(), err.Msg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
expectedErrorsIdx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a package given a number of compiler options and a file.
|
||||||
|
func testCompilePackage(t *testing.T, options *compileopts.Options, file string) (llvm.Module, []error) {
|
||||||
|
target, err := compileopts.LoadTarget(options)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to load target:", err)
|
||||||
|
}
|
||||||
|
config := &compileopts.Config{
|
||||||
|
Options: options,
|
||||||
|
Target: target,
|
||||||
|
}
|
||||||
|
compilerConfig := &Config{
|
||||||
|
Triple: config.Triple(),
|
||||||
|
Features: config.Features(),
|
||||||
|
ABI: config.ABI(),
|
||||||
|
GOOS: config.GOOS(),
|
||||||
|
GOARCH: config.GOARCH(),
|
||||||
|
CodeModel: config.CodeModel(),
|
||||||
|
RelocationModel: config.RelocationModel(),
|
||||||
|
Scheduler: config.Scheduler(),
|
||||||
|
AutomaticStackSize: config.AutomaticStackSize(),
|
||||||
|
DefaultStackSize: config.StackSize(),
|
||||||
|
NeedsStackObjects: config.NeedsStackObjects(),
|
||||||
|
}
|
||||||
|
machine, err := NewTargetMachine(compilerConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create target machine:", err)
|
||||||
|
}
|
||||||
|
defer machine.Dispose()
|
||||||
|
|
||||||
|
// Load entire program AST into memory.
|
||||||
|
lprogram, err := loader.Load(config, "./testdata/"+file, config.ClangHeaders, types.Config{
|
||||||
|
Sizes: Sizes(machine),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to create target machine:", err)
|
||||||
|
}
|
||||||
|
err = lprogram.Parse()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not parse test case %s: %s", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile AST to IR.
|
||||||
|
program := lprogram.LoadSSA()
|
||||||
|
pkg := lprogram.MainPkg()
|
||||||
|
return CompilePackage(file, pkg, program.Package(pkg.Pkg), machine, compilerConfig, false)
|
||||||
|
}
|
||||||
|
|
1
compiler/testdata/errors.go
предоставленный
Обычный файл
1
compiler/testdata/errors.go
предоставленный
Обычный файл
|
@ -0,0 +1 @@
|
||||||
|
package main
|
Загрузка…
Создание таблицы
Сослаться в новой задаче