From da89464a63a7c181e928a68f4ac392bd841a00b2 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 20 Oct 2018 17:22:51 +0200 Subject: [PATCH] compiler: compare slice against nil --- compiler/compiler.go | 13 +++++++++++++ testdata/slice.go | 2 ++ testdata/slice.txt | 2 ++ 3 files changed, 17 insertions(+) diff --git a/compiler/compiler.go b/compiler/compiler.go index f6063a0d..4d833061 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -2863,6 +2863,19 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error default: return llvm.Value{}, errors.New("todo: binop on pointer: " + binop.Op.String()) } + case *types.Slice: + // Slices are in general not comparable, but can be compared against + // nil. Assume at least one of them is nil to make the code easier. + xPtr := c.builder.CreateExtractValue(x, 0, "") + yPtr := c.builder.CreateExtractValue(y, 0, "") + switch binop.Op { + case token.EQL: // == + return c.builder.CreateICmp(llvm.IntEQ, xPtr, yPtr, ""), nil + case token.NEQ: // != + return c.builder.CreateICmp(llvm.IntNE, xPtr, yPtr, ""), nil + default: + return llvm.Value{}, errors.New("todo: binop on slice: " + binop.Op.String()) + } default: return llvm.Value{}, errors.New("unknown binop type: " + binop.X.Type().String()) } diff --git a/testdata/slice.go b/testdata/slice.go index c5e4a330..8fcbffff 100644 --- a/testdata/slice.go +++ b/testdata/slice.go @@ -4,6 +4,7 @@ func main() { l := 5 foo := []int{1, 2, 4, 5} bar := make([]int, l-2, l) + println("foo is nil?", foo == nil, nil == foo) printslice("foo", foo) printslice("bar", bar) printslice("foo[1:2]", foo[1:2]) @@ -15,6 +16,7 @@ func main() { // append var grow []int + println("slice is nil?", grow == nil, nil == grow) printslice("grow", grow) grow = append(grow, 42) printslice("grow", grow) diff --git a/testdata/slice.txt b/testdata/slice.txt index 81973655..75a32d10 100644 --- a/testdata/slice.txt +++ b/testdata/slice.txt @@ -1,9 +1,11 @@ +foo is nil? false false foo: len=4 cap=4 data: 1 2 4 5 bar: len=3 cap=5 data: 0 0 0 foo[1:2]: len=1 cap=3 data: 2 sum foo: 12 copy foo -> bar: 3 bar: len=3 cap=5 data: 1 2 4 +slice is nil? true true grow: len=0 cap=0 data: grow: len=1 cap=1 data: 42 grow: len=3 cap=4 data: 42 -1 -2