diff options
Diffstat (limited to 'llgo/test/execution/interfaces')
| -rw-r--r-- | llgo/test/execution/interfaces/assert.go | 61 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/basic.go | 43 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/comparei2i.go | 30 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/comparei2v.go | 13 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/e2i_conversion.go | 22 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/embedded.go | 32 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/error.go | 43 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/i2i_conversion.go | 33 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/import.go | 16 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/methods.go | 53 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/static_conversion.go | 35 | ||||
| -rw-r--r-- | llgo/test/execution/interfaces/wordsize.go | 40 |
12 files changed, 421 insertions, 0 deletions
diff --git a/llgo/test/execution/interfaces/assert.go b/llgo/test/execution/interfaces/assert.go new file mode 100644 index 00000000000..4c5db7dad77 --- /dev/null +++ b/llgo/test/execution/interfaces/assert.go @@ -0,0 +1,61 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: x is nil +// CHECK-NEXT: i2v: 123456 +// CHECK-NEXT: ! +// CHECK-NEXT: (*X).F1: 123456 + +package main + +type X struct{ x int } + +func (x *X) F1() { println("(*X).F1:", x.x) } +func (x *X) F2() { println("(*X).F2") } + +type I interface { + F1() + F2() +} + +func main() { + var x interface{} + + // x is nil. Let's make sure an assertion on it + // won't cause a panic. + if x, ok := x.(int32); ok { + println("i2v:", x) + } + if x == nil { + println("x is nil") + } + + x = int32(123456) + + // Let's try an interface-to-value assertion. + if x, ok := x.(int32); ok { + println("i2v:", x) + } + if x, ok := x.(int64); ok { + println("i2v:", x) + } + + // This will fail the assertion. + if i, ok := x.(I); ok { + i.F1() + _ = i + } else { + println("!") + } + + // Assign an *X, which should pass the assertion. + x_ := new(X) + x_.x = 123456 + x = x_ //&X{x: 123456} + if i, ok := x.(I); ok { + i.F1() + _ = i + } else { + println("!") + } +} diff --git a/llgo/test/execution/interfaces/basic.go b/llgo/test/execution/interfaces/basic.go new file mode 100644 index 00000000000..6c754dae1c9 --- /dev/null +++ b/llgo/test/execution/interfaces/basic.go @@ -0,0 +1,43 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: expected: y != z + +package main + +type any interface{} + +type Stringer interface { + String() string +} + +type lessThanAWord struct { + a byte +} + +func (l lessThanAWord) String() string { + return "!" +} + +func makeAStringer() Stringer { + return lessThanAWord{} +} + +func main() { + var x1, x2 int = 1, 2 + var y any = x1 + var z any = x2 + if y != z { + println("expected: y != z") + } else { + println("unexpected: y == z") + } + /* + if y == x1 { + println("expected: y == x1") + } else { + println("unexpected: y == x1") + } + */ + //println(y.(int)) +} diff --git a/llgo/test/execution/interfaces/comparei2i.go b/llgo/test/execution/interfaces/comparei2i.go new file mode 100644 index 00000000000..5a1f2660e21 --- /dev/null +++ b/llgo/test/execution/interfaces/comparei2i.go @@ -0,0 +1,30 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: true + +package main + +import "unsafe" + +type I interface { + X() +} + +type T int + +func (t T) X() { +} + +func main() { + var highbit uint32 = 1 << 31 + var pos0 float32 = 0 + var neg0 float32 = *(*float32)(unsafe.Pointer(&highbit)) + var i1 interface{} = pos0 + var i2 interface{} = neg0 + println(i1 == i2) + var i3 interface{} = T(123) + var i4 I = T(123) + println(i3 == i4) +} diff --git a/llgo/test/execution/interfaces/comparei2v.go b/llgo/test/execution/interfaces/comparei2v.go new file mode 100644 index 00000000000..6547360e60e --- /dev/null +++ b/llgo/test/execution/interfaces/comparei2v.go @@ -0,0 +1,13 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false + +package main + +func main() { + var x interface{} = 123 + println(x == 123) + println(x != 123) +} diff --git a/llgo/test/execution/interfaces/e2i_conversion.go b/llgo/test/execution/interfaces/e2i_conversion.go new file mode 100644 index 00000000000..6596e780678 --- /dev/null +++ b/llgo/test/execution/interfaces/e2i_conversion.go @@ -0,0 +1,22 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | count 0 + +package main + +import "io" + +type rdr struct{} + +func (r rdr) Read(b []byte) (int, error) { + return 0, nil +} + +func F(i interface{}) { + _ = i.(io.Reader) +} + +func main() { + var r rdr + F(r) + F(&r) +} diff --git a/llgo/test/execution/interfaces/embedded.go b/llgo/test/execution/interfaces/embedded.go new file mode 100644 index 00000000000..053afb1c602 --- /dev/null +++ b/llgo/test/execution/interfaces/embedded.go @@ -0,0 +1,32 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: A +// CHECK-NEXT: B + +package main + +type BI interface { + B() +} + +type AI interface { + A() + BI +} + +type S struct{} + +func (s S) A() { + println("A") +} + +func (s S) B() { + println("B") +} + +func main() { + var ai AI = S{} + ai.A() + ai.B() +} diff --git a/llgo/test/execution/interfaces/error.go b/llgo/test/execution/interfaces/error.go new file mode 100644 index 00000000000..17244360e0b --- /dev/null +++ b/llgo/test/execution/interfaces/error.go @@ -0,0 +1,43 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: !!!! 123 +// CHECK-NEXT: errno 123 + +package main + +var errors = [...]string{} + +func itoa(val int) string { // do it here rather than with fmt to avoid dependency + if val < 0 { + return "-" + itoa(-val) + } + var buf [32]byte // big enough for int64 + i := len(buf) - 1 + for val >= 10 { + buf[i] = byte(val%10 + '0') + i-- + val /= 10 + } + buf[i] = byte(val + '0') + return string(buf[i:]) +} + +type Errno uintptr + +func (e Errno) Error() string { + println("!!!!", uintptr(e)) + if 0 <= int(e) && int(e) < len(errors) { + s := errors[e] + if s != "" { + return s + } + } + return "errno " + itoa(int(e)) +} + +func main() { + e := Errno(123) + i := (interface{})(e) + println(i.(error).Error()) +} diff --git a/llgo/test/execution/interfaces/i2i_conversion.go b/llgo/test/execution/interfaces/i2i_conversion.go new file mode 100644 index 00000000000..b55d8404a12 --- /dev/null +++ b/llgo/test/execution/interfaces/i2i_conversion.go @@ -0,0 +1,33 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 666 +// CHECK-NEXT: The Beast + +package main + +type Numbered interface { + Number() int +} + +type Named interface { + Name() string +} + +type Beast struct{} + +func (b *Beast) Number() int { + return 666 +} + +func (b *Beast) Name() string { + return "The Beast" +} + +func main() { + var b Beast + var numbered Numbered = &b + var named Named = numbered.(Named) + println(numbered.Number()) + println(named.Name()) +} diff --git a/llgo/test/execution/interfaces/import.go b/llgo/test/execution/interfaces/import.go new file mode 100644 index 00000000000..3305ee6a849 --- /dev/null +++ b/llgo/test/execution/interfaces/import.go @@ -0,0 +1,16 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +package main + +import "syscall" + +type Signal interface { + Signal() +} + +func main() { + var s Signal = syscall.SIGINT + // CHECK: ({{.*}},{{.*}}) + println(s) +} diff --git a/llgo/test/execution/interfaces/methods.go b/llgo/test/execution/interfaces/methods.go new file mode 100644 index 00000000000..5fb704cd9b1 --- /dev/null +++ b/llgo/test/execution/interfaces/methods.go @@ -0,0 +1,53 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: X() +// CHECK-NEXT: Y() +// CHECK-NEXT: X() +// CHECK-NEXT: Y() +// CHECK-NEXT: X() + +package main + +type Stringer interface { + String() string +} + +type X int +type Y int + +type Z1 struct { + X +} + +type Z2 struct { + Stringer +} + +func (x X) String() string { + return "X()" +} + +func (y *Y) String() string { + return "Y()" +} + +func makeX() X { + return X(0) +} + +func main() { + var z Stringer = X(0) + println(z.String()) + + z = new(Y) + println(z.String()) + + z = Z1{} + println(z.String()) + + z = Z2{new(Y)} + println(z.String()) + + println(makeX().String()) +} diff --git a/llgo/test/execution/interfaces/static_conversion.go b/llgo/test/execution/interfaces/static_conversion.go new file mode 100644 index 00000000000..e63f10d64ad --- /dev/null +++ b/llgo/test/execution/interfaces/static_conversion.go @@ -0,0 +1,35 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 666 +// CHECK-NEXT: 3 + +package main + +type Blah interface{} +type Numbered interface { + Blah + Number() int +} + +type Beast struct{} + +func (b *Beast) Number() int { + return 666 +} + +type MagicNumber int + +func (m MagicNumber) Number() int { + return int(m) +} + +func main() { + var b Beast + var m MagicNumber = 3 + var n Numbered = &b + println(n.Number()) + + n = m + println(n.Number()) +} diff --git a/llgo/test/execution/interfaces/wordsize.go b/llgo/test/execution/interfaces/wordsize.go new file mode 100644 index 00000000000..e2de5d54895 --- /dev/null +++ b/llgo/test/execution/interfaces/wordsize.go @@ -0,0 +1,40 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: StringStringer(abc) +// CHECK-NEXT: abc 1 2 3 + +package main + +type Stringer interface { + String() string +} + +type StringStringer string + +func (s StringStringer) String() string { + return "StringStringer(" + string(s) + ")" +} + +func (s StringStringer) MethodWithArgs(a, b, c int) { + println(s, a, b, c) +} + +type I interface { + MethodWithArgs(a, b, c int) +} + +func testLargerThanWord() { + // string is larger than a word. Make sure it works + // well as a method receiver when using interfaces. + var s Stringer = StringStringer("abc") + println(s.String()) + + // Test calling a method which takes parameters + // beyond the receiver. + s.(I).MethodWithArgs(1, 2, 3) +} + +func main() { + testLargerThanWord() +} |

