github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/transform/allocs_test.go (about) 1 package transform_test 2 3 import ( 4 "go/token" 5 "os" 6 "path/filepath" 7 "regexp" 8 "sort" 9 "strconv" 10 "strings" 11 "testing" 12 13 "github.com/tinygo-org/tinygo/transform" 14 "tinygo.org/x/go-llvm" 15 ) 16 17 func TestAllocs(t *testing.T) { 18 t.Parallel() 19 testTransform(t, "testdata/allocs", func(mod llvm.Module) { 20 transform.OptimizeAllocs(mod, nil, 256, nil) 21 }) 22 } 23 24 type allocsTestOutput struct { 25 filename string 26 line int 27 msg string 28 } 29 30 func (out allocsTestOutput) String() string { 31 return out.filename + ":" + strconv.Itoa(out.line) + ": " + out.msg 32 } 33 34 // Test with a Go file as input (for more accurate tests). 35 func TestAllocs2(t *testing.T) { 36 t.Parallel() 37 38 mod := compileGoFileForTesting(t, "./testdata/allocs2.go") 39 40 // Run functionattrs pass, which is necessary for escape analysis. 41 po := llvm.NewPassBuilderOptions() 42 defer po.Dispose() 43 err := mod.RunPasses("function(instcombine),function-attrs", llvm.TargetMachine{}, po) 44 if err != nil { 45 t.Error("failed to run passes:", err) 46 } 47 48 // Run heap to stack transform. 49 var testOutputs []allocsTestOutput 50 transform.OptimizeAllocs(mod, regexp.MustCompile("."), 256, func(pos token.Position, msg string) { 51 testOutputs = append(testOutputs, allocsTestOutput{ 52 filename: filepath.Base(pos.Filename), 53 line: pos.Line, 54 msg: msg, 55 }) 56 }) 57 sort.Slice(testOutputs, func(i, j int) bool { 58 return testOutputs[i].line < testOutputs[j].line 59 }) 60 testOutput := "" 61 for _, out := range testOutputs { 62 testOutput += out.String() + "\n" 63 } 64 65 // Load expected test output (the OUT: lines). 66 testInput, err := os.ReadFile("./testdata/allocs2.go") 67 if err != nil { 68 t.Fatal("could not read test input:", err) 69 } 70 var expectedTestOutput string 71 for i, line := range strings.Split(strings.ReplaceAll(string(testInput), "\r\n", "\n"), "\n") { 72 if idx := strings.Index(line, " // OUT: "); idx > 0 { 73 msg := line[idx+len(" // OUT: "):] 74 expectedTestOutput += "allocs2.go:" + strconv.Itoa(i+1) + ": " + msg + "\n" 75 } 76 } 77 78 if testOutput != expectedTestOutput { 79 t.Errorf("output does not match expected output:\n%s", testOutput) 80 } 81 }