blob: 44dc1db12e175e2de060a87706f8892901c0239c [file] [log] [blame]
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import (
"reflect"
"sort"
"testing"
)
func typeWithoutPointers() *Type {
return &Type{Etype: TSTRUCT, Extra: &StructType{Haspointers: 1}} // haspointers -> false
}
func typeWithPointers() *Type {
return &Type{Etype: TSTRUCT, Extra: &StructType{Haspointers: 2}} // haspointers -> true
}
// Test all code paths for cmpstackvarlt.
func TestCmpstackvar(t *testing.T) {
testdata := []struct {
a, b Node
lt bool
}{
{
Node{Class: PAUTO},
Node{Class: PFUNC},
false,
},
{
Node{Class: PFUNC},
Node{Class: PAUTO},
true,
},
{
Node{Class: PFUNC, Xoffset: 0},
Node{Class: PFUNC, Xoffset: 10},
true,
},
{
Node{Class: PFUNC, Xoffset: 20},
Node{Class: PFUNC, Xoffset: 10},
false,
},
{
Node{Class: PFUNC, Xoffset: 10},
Node{Class: PFUNC, Xoffset: 10},
false,
},
{
Node{Class: PPARAM, Xoffset: 10},
Node{Class: PPARAMOUT, Xoffset: 20},
true,
},
{
Node{Class: PPARAMOUT, Xoffset: 10},
Node{Class: PPARAM, Xoffset: 20},
true,
},
{
Node{Class: PAUTO, Used: true},
Node{Class: PAUTO, Used: false},
true,
},
{
Node{Class: PAUTO, Used: false},
Node{Class: PAUTO, Used: true},
false,
},
{
Node{Class: PAUTO, Type: typeWithoutPointers()},
Node{Class: PAUTO, Type: typeWithPointers()},
false,
},
{
Node{Class: PAUTO, Type: typeWithPointers()},
Node{Class: PAUTO, Type: typeWithoutPointers()},
true,
},
{
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: false}},
true,
},
{
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: false}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}},
false,
},
{
Node{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}},
Node{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}},
false,
},
{
Node{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}},
Node{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}},
true,
},
{
Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
true,
},
{
Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
false,
},
{
Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
false,
},
}
for _, d := range testdata {
got := cmpstackvarlt(&d.a, &d.b)
if got != d.lt {
t.Errorf("want %#v < %#v", d.a, d.b)
}
// If we expect a < b to be true, check that b < a is false.
if d.lt && cmpstackvarlt(&d.b, &d.a) {
t.Errorf("unexpected %#v < %#v", d.b, d.a)
}
}
}
func TestStackvarSort(t *testing.T) {
inp := []*Node{
{Class: PFUNC, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Used: true, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
}
want := []*Node{
{Class: PFUNC, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Used: true, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "xyz"}},
{Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}},
}
// haspointers updates Type.Haspointers as a side effect, so
// exercise this function on all inputs so that reflect.DeepEqual
// doesn't produce false positives.
for i := range want {
haspointers(want[i].Type)
haspointers(inp[i].Type)
}
sort.Sort(byStackVar(inp))
if !reflect.DeepEqual(want, inp) {
t.Error("sort failed")
for i := range inp {
g := inp[i]
w := want[i]
eq := reflect.DeepEqual(w, g)
if !eq {
t.Log(i, w, g)
}
}
}
}