github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/cmd/compile/internal/gc/ssa_test.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gc
     6  
     7  import (
     8  	"bytes"
     9  	"internal/testenv"
    10  	"io/ioutil"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"runtime"
    14  	"strings"
    15  	"testing"
    16  )
    17  
    18  // TODO: move all these tests elsewhere?
    19  // Perhaps teach test/run.go how to run them with a new action verb.
    20  func runTest(t *testing.T, filename string) {
    21  	t.Parallel()
    22  	doTest(t, filename, "run")
    23  }
    24  func buildTest(t *testing.T, filename string) {
    25  	t.Parallel()
    26  	doTest(t, filename, "build")
    27  }
    28  func doTest(t *testing.T, filename string, kind string) {
    29  	testenv.MustHaveGoBuild(t)
    30  	gotool := testenv.GoToolPath(t)
    31  
    32  	var stdout, stderr bytes.Buffer
    33  	cmd := exec.Command(gotool, kind, "-gcflags=-d=ssa/check/on", filepath.Join("testdata", filename))
    34  	cmd.Stdout = &stdout
    35  	cmd.Stderr = &stderr
    36  	err := cmd.Run()
    37  	if err != nil {
    38  		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
    39  	}
    40  	if s := stdout.String(); s != "" {
    41  		t.Errorf("Stdout = %s\nWant empty", s)
    42  	}
    43  	if s := stderr.String(); strings.Contains(s, "SSA unimplemented") {
    44  		t.Errorf("Unimplemented message found in stderr:\n%s", s)
    45  	}
    46  }
    47  
    48  // runGenTest runs a test-generator, then runs the generated test.
    49  // Generated test can either fail in compilation or execution.
    50  // The environment variable parameter(s) is passed to the run
    51  // of the generated test.
    52  func runGenTest(t *testing.T, filename, tmpname string, ev ...string) {
    53  	testenv.MustHaveGoRun(t)
    54  	gotool := testenv.GoToolPath(t)
    55  	var stdout, stderr bytes.Buffer
    56  	cmd := exec.Command(gotool, "run", filepath.Join("testdata", filename))
    57  	cmd.Stdout = &stdout
    58  	cmd.Stderr = &stderr
    59  	if err := cmd.Run(); err != nil {
    60  		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
    61  	}
    62  	// Write stdout into a temporary file
    63  	tmpdir, ok := ioutil.TempDir("", tmpname)
    64  	if ok != nil {
    65  		t.Fatalf("Failed to create temporary directory")
    66  	}
    67  
    68  	rungo := filepath.Join(tmpdir, "run.go")
    69  	ok = ioutil.WriteFile(rungo, stdout.Bytes(), 0600)
    70  	if ok != nil {
    71  		t.Fatalf("Failed to create temporary file " + rungo)
    72  	}
    73  
    74  	stdout.Reset()
    75  	stderr.Reset()
    76  	cmd = exec.Command("go", "run", "-gcflags=-d=ssa/check/on", rungo)
    77  	cmd.Stdout = &stdout
    78  	cmd.Stderr = &stderr
    79  	cmd.Env = append(cmd.Env, ev...)
    80  	err := cmd.Run()
    81  	if err != nil {
    82  		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
    83  	}
    84  	if s := stderr.String(); s != "" {
    85  		t.Errorf("Stderr = %s\nWant empty", s)
    86  	}
    87  	if s := stdout.String(); s != "" {
    88  		t.Errorf("Stdout = %s\nWant empty", s)
    89  	}
    90  }
    91  
    92  func TestGenFlowGraph(t *testing.T) {
    93  	runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp1")
    94  	if runtime.GOOS != "windows" {
    95  		runGenTest(t, "flowgraph_generator1.go", "ssa_fg_tmp2", "GO_SSA_PHI_LOC_CUTOFF=0")
    96  	}
    97  }
    98  
    99  // TestShortCircuit tests OANDAND and OOROR expressions and short circuiting.
   100  func TestShortCircuit(t *testing.T) { runTest(t, "short.go") }
   101  
   102  // TestBreakContinue tests that continue and break statements do what they say.
   103  func TestBreakContinue(t *testing.T) { runTest(t, "break.go") }
   104  
   105  // TestTypeAssertion tests type assertions.
   106  func TestTypeAssertion(t *testing.T) { runTest(t, "assert.go") }
   107  
   108  // TestArithmetic tests that both backends have the same result for arithmetic expressions.
   109  func TestArithmetic(t *testing.T) { runTest(t, "arith.go") }
   110  
   111  // TestFP tests that both backends have the same result for floating point expressions.
   112  func TestFP(t *testing.T) { runTest(t, "fp.go") }
   113  
   114  // TestArithmeticBoundary tests boundary results for arithmetic operations.
   115  func TestArithmeticBoundary(t *testing.T) { runTest(t, "arithBoundary.go") }
   116  
   117  // TestArithmeticConst tests results for arithmetic operations against constants.
   118  func TestArithmeticConst(t *testing.T) { runTest(t, "arithConst.go") }
   119  
   120  func TestChan(t *testing.T) { runTest(t, "chan.go") }
   121  
   122  // TestComparisonsConst tests results for comparison operations against constants.
   123  func TestComparisonsConst(t *testing.T) { runTest(t, "cmpConst.go") }
   124  
   125  func TestCompound(t *testing.T) { runTest(t, "compound.go") }
   126  
   127  func TestCtl(t *testing.T) { runTest(t, "ctl.go") }
   128  
   129  func TestLoadStore(t *testing.T) { runTest(t, "loadstore.go") }
   130  
   131  func TestMap(t *testing.T) { runTest(t, "map.go") }
   132  
   133  func TestRegalloc(t *testing.T) { runTest(t, "regalloc.go") }
   134  
   135  func TestString(t *testing.T) { runTest(t, "string.go") }
   136  
   137  func TestDeferNoReturn(t *testing.T) { buildTest(t, "deferNoReturn.go") }
   138  
   139  // TestClosure tests closure related behavior.
   140  func TestClosure(t *testing.T) { runTest(t, "closure.go") }
   141  
   142  func TestArray(t *testing.T) { runTest(t, "array.go") }
   143  
   144  func TestAppend(t *testing.T) { runTest(t, "append.go") }
   145  
   146  func TestZero(t *testing.T) { runTest(t, "zero.go") }
   147  
   148  func TestAddressed(t *testing.T) { runTest(t, "addressed.go") }
   149  
   150  func TestCopy(t *testing.T) { runTest(t, "copy.go") }
   151  
   152  func TestUnsafe(t *testing.T) { runTest(t, "unsafe.go") }
   153  
   154  func TestPhi(t *testing.T) { runTest(t, "phi.go") }
   155  
   156  func TestSlice(t *testing.T) { runTest(t, "slice.go") }
   157  
   158  func TestNamedReturn(t *testing.T) { runTest(t, "namedReturn.go") }
   159  
   160  func TestDuplicateLoad(t *testing.T) { runTest(t, "dupLoad.go") }
   161  
   162  func TestSqrt(t *testing.T) { runTest(t, "sqrt_const.go") }