Skip to content

Commit a242937

Browse files
committed
compiler: add tests for error messages
The test is currently empty, but will be used in the next commit.
1 parent d4748bf commit a242937

File tree

2 files changed

+86
-43
lines changed

2 files changed

+86
-43
lines changed

compiler/compiler_test.go

+85-43
Original file line numberDiff line numberDiff line change
@@ -70,60 +70,19 @@ func TestCompiler(t *testing.T) {
7070
options := &compileopts.Options{
7171
Target: targetString,
7272
}
73-
target, err := compileopts.LoadTarget(options)
74-
if err != nil {
75-
t.Fatal("failed to load target:", err)
76-
}
7773
if tc.scheduler != "" {
7874
options.Scheduler = tc.scheduler
7975
}
80-
config := &compileopts.Config{
81-
Options: options,
82-
Target: target,
83-
}
84-
compilerConfig := &Config{
85-
Triple: config.Triple(),
86-
Features: config.Features(),
87-
ABI: config.ABI(),
88-
GOOS: config.GOOS(),
89-
GOARCH: config.GOARCH(),
90-
CodeModel: config.CodeModel(),
91-
RelocationModel: config.RelocationModel(),
92-
Scheduler: config.Scheduler(),
93-
AutomaticStackSize: config.AutomaticStackSize(),
94-
DefaultStackSize: config.StackSize(),
95-
NeedsStackObjects: config.NeedsStackObjects(),
96-
}
97-
machine, err := NewTargetMachine(compilerConfig)
98-
if err != nil {
99-
t.Fatal("failed to create target machine:", err)
100-
}
101-
defer machine.Dispose()
102-
103-
// Load entire program AST into memory.
104-
lprogram, err := loader.Load(config, "./testdata/"+tc.file, config.ClangHeaders, types.Config{
105-
Sizes: Sizes(machine),
106-
})
107-
if err != nil {
108-
t.Fatal("failed to create target machine:", err)
109-
}
110-
err = lprogram.Parse()
111-
if err != nil {
112-
t.Fatalf("could not parse test case %s: %s", tc.file, err)
113-
}
11476

115-
// Compile AST to IR.
116-
program := lprogram.LoadSSA()
117-
pkg := lprogram.MainPkg()
118-
mod, errs := CompilePackage(tc.file, pkg, program.Package(pkg.Pkg), machine, compilerConfig, false)
77+
mod, errs := testCompilePackage(t, options, tc.file)
11978
if errs != nil {
12079
for _, err := range errs {
12180
t.Error(err)
12281
}
12382
return
12483
}
12584

126-
err = llvm.VerifyModule(mod, llvm.PrintMessageAction)
85+
err := llvm.VerifyModule(mod, llvm.PrintMessageAction)
12786
if err != nil {
12887
t.Error(err)
12988
}
@@ -216,3 +175,86 @@ func filterIrrelevantIRLines(lines []string) []string {
216175
}
217176
return out
218177
}
178+
179+
func TestCompilerErrors(t *testing.T) {
180+
t.Parallel()
181+
182+
// Read expected errors from the test file.
183+
var expectedErrors []string
184+
errorsFile, err := os.ReadFile("testdata/errors.go")
185+
if err != nil {
186+
t.Error(err)
187+
}
188+
errorsFileString := strings.ReplaceAll(string(errorsFile), "\r\n", "\n")
189+
for _, line := range strings.Split(errorsFileString, "\n") {
190+
if strings.HasPrefix(line, "// ERROR: ") {
191+
expectedErrors = append(expectedErrors, strings.TrimPrefix(line, "// ERROR: "))
192+
}
193+
}
194+
195+
// Compile the Go file with errors.
196+
options := &compileopts.Options{
197+
Target: "wasm",
198+
}
199+
_, errs := testCompilePackage(t, options, "errors.go")
200+
201+
// Check whether the actual errors match the expected errors.
202+
expectedErrorsIdx := 0
203+
for _, err := range errs {
204+
err := err.(types.Error)
205+
position := err.Fset.Position(err.Pos)
206+
position.Filename = "errors.go" // don't use a full path
207+
if expectedErrorsIdx >= len(expectedErrors) || expectedErrors[expectedErrorsIdx] != err.Msg {
208+
t.Errorf("unexpected compiler error: %s: %s", position.String(), err.Msg)
209+
continue
210+
}
211+
expectedErrorsIdx++
212+
}
213+
}
214+
215+
// Build a package given a number of compiler options and a file.
216+
func testCompilePackage(t *testing.T, options *compileopts.Options, file string) (llvm.Module, []error) {
217+
target, err := compileopts.LoadTarget(options)
218+
if err != nil {
219+
t.Fatal("failed to load target:", err)
220+
}
221+
config := &compileopts.Config{
222+
Options: options,
223+
Target: target,
224+
}
225+
compilerConfig := &Config{
226+
Triple: config.Triple(),
227+
Features: config.Features(),
228+
ABI: config.ABI(),
229+
GOOS: config.GOOS(),
230+
GOARCH: config.GOARCH(),
231+
CodeModel: config.CodeModel(),
232+
RelocationModel: config.RelocationModel(),
233+
Scheduler: config.Scheduler(),
234+
AutomaticStackSize: config.AutomaticStackSize(),
235+
DefaultStackSize: config.StackSize(),
236+
NeedsStackObjects: config.NeedsStackObjects(),
237+
}
238+
machine, err := NewTargetMachine(compilerConfig)
239+
if err != nil {
240+
t.Fatal("failed to create target machine:", err)
241+
}
242+
defer machine.Dispose()
243+
244+
// Load entire program AST into memory.
245+
lprogram, err := loader.Load(config, "./testdata/"+file, config.ClangHeaders, types.Config{
246+
Sizes: Sizes(machine),
247+
})
248+
if err != nil {
249+
t.Fatal("failed to create target machine:", err)
250+
}
251+
err = lprogram.Parse()
252+
if err != nil {
253+
t.Fatalf("could not parse test case %s: %s", file, err)
254+
}
255+
256+
// Compile AST to IR.
257+
program := lprogram.LoadSSA()
258+
pkg := lprogram.MainPkg()
259+
return CompilePackage(file, pkg, program.Package(pkg.Pkg), machine, compilerConfig, false)
260+
}

compiler/testdata/errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package main

0 commit comments

Comments
 (0)