Home | History | Annotate | Download | only in gc
      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 	"reflect"
      9 	"sort"
     10 	"testing"
     11 )
     12 
     13 func typeWithoutPointers() *Type {
     14 	return &Type{Etype: TSTRUCT, Extra: &StructType{Haspointers: 1}} // haspointers -> false
     15 }
     16 
     17 func typeWithPointers() *Type {
     18 	return &Type{Etype: TSTRUCT, Extra: &StructType{Haspointers: 2}} // haspointers -> true
     19 }
     20 
     21 // Test all code paths for cmpstackvarlt.
     22 func TestCmpstackvar(t *testing.T) {
     23 	testdata := []struct {
     24 		a, b Node
     25 		lt   bool
     26 	}{
     27 		{
     28 			Node{Class: PAUTO},
     29 			Node{Class: PFUNC},
     30 			false,
     31 		},
     32 		{
     33 			Node{Class: PFUNC},
     34 			Node{Class: PAUTO},
     35 			true,
     36 		},
     37 		{
     38 			Node{Class: PFUNC, Xoffset: 0},
     39 			Node{Class: PFUNC, Xoffset: 10},
     40 			true,
     41 		},
     42 		{
     43 			Node{Class: PFUNC, Xoffset: 20},
     44 			Node{Class: PFUNC, Xoffset: 10},
     45 			false,
     46 		},
     47 		{
     48 			Node{Class: PFUNC, Xoffset: 10},
     49 			Node{Class: PFUNC, Xoffset: 10},
     50 			false,
     51 		},
     52 		{
     53 			Node{Class: PPARAM, Xoffset: 10},
     54 			Node{Class: PPARAMOUT, Xoffset: 20},
     55 			true,
     56 		},
     57 		{
     58 			Node{Class: PPARAMOUT, Xoffset: 10},
     59 			Node{Class: PPARAM, Xoffset: 20},
     60 			true,
     61 		},
     62 		{
     63 			Node{Class: PAUTO, Used: true},
     64 			Node{Class: PAUTO, Used: false},
     65 			true,
     66 		},
     67 		{
     68 			Node{Class: PAUTO, Used: false},
     69 			Node{Class: PAUTO, Used: true},
     70 			false,
     71 		},
     72 		{
     73 			Node{Class: PAUTO, Type: typeWithoutPointers()},
     74 			Node{Class: PAUTO, Type: typeWithPointers()},
     75 			false,
     76 		},
     77 		{
     78 			Node{Class: PAUTO, Type: typeWithPointers()},
     79 			Node{Class: PAUTO, Type: typeWithoutPointers()},
     80 			true,
     81 		},
     82 		{
     83 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}},
     84 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: false}},
     85 			true,
     86 		},
     87 		{
     88 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: false}},
     89 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}},
     90 			false,
     91 		},
     92 		{
     93 			Node{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}},
     94 			Node{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}},
     95 			false,
     96 		},
     97 		{
     98 			Node{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}},
     99 			Node{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}},
    100 			true,
    101 		},
    102 		{
    103 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
    104 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
    105 			true,
    106 		},
    107 		{
    108 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
    109 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
    110 			false,
    111 		},
    112 		{
    113 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
    114 			Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
    115 			false,
    116 		},
    117 	}
    118 	for _, d := range testdata {
    119 		got := cmpstackvarlt(&d.a, &d.b)
    120 		if got != d.lt {
    121 			t.Errorf("want %#v < %#v", d.a, d.b)
    122 		}
    123 		// If we expect a < b to be true, check that b < a is false.
    124 		if d.lt && cmpstackvarlt(&d.b, &d.a) {
    125 			t.Errorf("unexpected %#v < %#v", d.b, d.a)
    126 		}
    127 	}
    128 }
    129 
    130 func TestStackvarSort(t *testing.T) {
    131 	inp := []*Node{
    132 		{Class: PFUNC, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    133 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    134 		{Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    135 		{Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    136 		{Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    137 		{Class: PAUTO, Used: true, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    138 		{Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}},
    139 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    140 		{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}, Sym: &Sym{}},
    141 		{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}},
    142 		{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}},
    143 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
    144 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
    145 	}
    146 	want := []*Node{
    147 		{Class: PFUNC, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    148 		{Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    149 		{Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    150 		{Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    151 		{Class: PAUTO, Used: true, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    152 		{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}, Sym: &Sym{}},
    153 		{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}},
    154 		{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}},
    155 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    156 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
    157 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
    158 		{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
    159 		{Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}},
    160 	}
    161 	// haspointers updates Type.Haspointers as a side effect, so
    162 	// exercise this function on all inputs so that reflect.DeepEqual
    163 	// doesn't produce false positives.
    164 	for i := range want {
    165 		haspointers(want[i].Type)
    166 		haspointers(inp[i].Type)
    167 	}
    168 
    169 	sort.Sort(byStackVar(inp))
    170 	if !reflect.DeepEqual(want, inp) {
    171 		t.Error("sort failed")
    172 		for i := range inp {
    173 			g := inp[i]
    174 			w := want[i]
    175 			eq := reflect.DeepEqual(w, g)
    176 			if !eq {
    177 				t.Log(i, w, g)
    178 			}
    179 		}
    180 	}
    181 }
    182