diff options
Diffstat (limited to 'llgo/test')
105 files changed, 4229 insertions, 0 deletions
diff --git a/llgo/test/CMakeLists.txt b/llgo/test/CMakeLists.txt new file mode 100644 index 00000000000..641ade8322a --- /dev/null +++ b/llgo/test/CMakeLists.txt @@ -0,0 +1,15 @@ +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + +add_lit_testsuite(check-llgo "Running the llgo regression tests" + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS + FileCheck + count + llgo + libgo + not + ) +set_target_properties(check-llgo PROPERTIES FOLDER "Tests") diff --git a/llgo/test/debuginfo/emptyname.go b/llgo/test/debuginfo/emptyname.go new file mode 100644 index 00000000000..28ad10df514 --- /dev/null +++ b/llgo/test/debuginfo/emptyname.go @@ -0,0 +1,7 @@ +// RUN: llgo -c -o /dev/null -g %s + +package main + +//line :1 +func main() { +} diff --git a/llgo/test/driver/parse-arguments.go b/llgo/test/driver/parse-arguments.go new file mode 100644 index 00000000000..36b3c5c615c --- /dev/null +++ b/llgo/test/driver/parse-arguments.go @@ -0,0 +1,17 @@ +// RUN: not llgo -B 2>&1 | FileCheck --check-prefix=B %s +// RUN: not llgo -D 2>&1 | FileCheck --check-prefix=D %s +// RUN: not llgo -I 2>&1 | FileCheck --check-prefix=I %s +// RUN: not llgo -isystem 2>&1 | FileCheck --check-prefix=isystem %s +// RUN: not llgo -L 2>&1 | FileCheck --check-prefix=L %s +// RUN: not llgo -fload-plugin 2>&1 | FileCheck --check-prefix=fload-plugin %s +// RUN: not llgo -mllvm 2>&1 | FileCheck --check-prefix=mllvm %s +// RUN: not llgo -o 2>&1 | FileCheck --check-prefix=o %s + +// B: missing argument after '-B' +// D: missing argument after '-D' +// I: missing argument after '-I' +// isystem: missing argument after '-isystem' +// L: missing argument after '-L' +// fload-plugin: missing argument after '-fload-plugin' +// mllvm: missing argument after '-mllvm' +// o: missing argument after '-o' diff --git a/llgo/test/execution/Inputs/init2.go b/llgo/test/execution/Inputs/init2.go new file mode 100644 index 00000000000..041d7647b3e --- /dev/null +++ b/llgo/test/execution/Inputs/init2.go @@ -0,0 +1,5 @@ +package main + +func init() { + println("do some other stuff before main") +} diff --git a/llgo/test/execution/arrays/compare.go b/llgo/test/execution/arrays/compare.go new file mode 100644 index 00000000000..b99d4fd8f8e --- /dev/null +++ b/llgo/test/execution/arrays/compare.go @@ -0,0 +1,18 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: false +// CHECK-NEXT: true +// CHECK-NEXT: false + +package main + +func main() { + a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + b := [...]int{10, 1, 2, 3, 4, 5, 6, 7, 8, 9} + c := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + + println(a == b) + println(a == c) + println(b == c) +} diff --git a/llgo/test/execution/arrays/index.go b/llgo/test/execution/arrays/index.go new file mode 100644 index 00000000000..78c53150aa2 --- /dev/null +++ b/llgo/test/execution/arrays/index.go @@ -0,0 +1,288 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 5 +// CHECK-NEXT: 6 +// CHECK-NEXT: 7 +// CHECK-NEXT: 8 +// CHECK-NEXT: 9 +// CHECK-NEXT: 10 +// CHECK-NEXT: 11 +// CHECK-NEXT: 12 +// CHECK-NEXT: 13 +// CHECK-NEXT: 14 +// CHECK-NEXT: 15 +// CHECK-NEXT: 16 +// CHECK-NEXT: 17 +// CHECK-NEXT: 18 +// CHECK-NEXT: 19 +// CHECK-NEXT: 20 +// CHECK-NEXT: 21 +// CHECK-NEXT: 22 +// CHECK-NEXT: 23 +// CHECK-NEXT: 24 +// CHECK-NEXT: 25 +// CHECK-NEXT: 26 +// CHECK-NEXT: 27 +// CHECK-NEXT: 28 +// CHECK-NEXT: 29 +// CHECK-NEXT: 30 +// CHECK-NEXT: 31 +// CHECK-NEXT: 32 +// CHECK-NEXT: 33 +// CHECK-NEXT: 34 +// CHECK-NEXT: 35 +// CHECK-NEXT: 36 +// CHECK-NEXT: 37 +// CHECK-NEXT: 38 +// CHECK-NEXT: 39 +// CHECK-NEXT: 40 +// CHECK-NEXT: 41 +// CHECK-NEXT: 42 +// CHECK-NEXT: 43 +// CHECK-NEXT: 44 +// CHECK-NEXT: 45 +// CHECK-NEXT: 46 +// CHECK-NEXT: 47 +// CHECK-NEXT: 48 +// CHECK-NEXT: 49 +// CHECK-NEXT: 50 +// CHECK-NEXT: 51 +// CHECK-NEXT: 52 +// CHECK-NEXT: 53 +// CHECK-NEXT: 54 +// CHECK-NEXT: 55 +// CHECK-NEXT: 56 +// CHECK-NEXT: 57 +// CHECK-NEXT: 58 +// CHECK-NEXT: 59 +// CHECK-NEXT: 60 +// CHECK-NEXT: 61 +// CHECK-NEXT: 62 +// CHECK-NEXT: 63 +// CHECK-NEXT: 64 +// CHECK-NEXT: 65 +// CHECK-NEXT: 66 +// CHECK-NEXT: 67 +// CHECK-NEXT: 68 +// CHECK-NEXT: 69 +// CHECK-NEXT: 70 +// CHECK-NEXT: 71 +// CHECK-NEXT: 72 +// CHECK-NEXT: 73 +// CHECK-NEXT: 74 +// CHECK-NEXT: 75 +// CHECK-NEXT: 76 +// CHECK-NEXT: 77 +// CHECK-NEXT: 78 +// CHECK-NEXT: 79 +// CHECK-NEXT: 80 +// CHECK-NEXT: 81 +// CHECK-NEXT: 82 +// CHECK-NEXT: 83 +// CHECK-NEXT: 84 +// CHECK-NEXT: 85 +// CHECK-NEXT: 86 +// CHECK-NEXT: 87 +// CHECK-NEXT: 88 +// CHECK-NEXT: 89 +// CHECK-NEXT: 90 +// CHECK-NEXT: 91 +// CHECK-NEXT: 92 +// CHECK-NEXT: 93 +// CHECK-NEXT: 94 +// CHECK-NEXT: 95 +// CHECK-NEXT: 96 +// CHECK-NEXT: 97 +// CHECK-NEXT: 98 +// CHECK-NEXT: 99 +// CHECK-NEXT: 100 +// CHECK-NEXT: 101 +// CHECK-NEXT: 102 +// CHECK-NEXT: 103 +// CHECK-NEXT: 104 +// CHECK-NEXT: 105 +// CHECK-NEXT: 106 +// CHECK-NEXT: 107 +// CHECK-NEXT: 108 +// CHECK-NEXT: 109 +// CHECK-NEXT: 110 +// CHECK-NEXT: 111 +// CHECK-NEXT: 112 +// CHECK-NEXT: 113 +// CHECK-NEXT: 114 +// CHECK-NEXT: 115 +// CHECK-NEXT: 116 +// CHECK-NEXT: 117 +// CHECK-NEXT: 118 +// CHECK-NEXT: 119 +// CHECK-NEXT: 120 +// CHECK-NEXT: 121 +// CHECK-NEXT: 122 +// CHECK-NEXT: 123 +// CHECK-NEXT: 124 +// CHECK-NEXT: 125 +// CHECK-NEXT: 126 +// CHECK-NEXT: 127 +// CHECK-NEXT: 128 +// CHECK-NEXT: 129 +// CHECK-NEXT: 130 +// CHECK-NEXT: 131 +// CHECK-NEXT: 132 +// CHECK-NEXT: 133 +// CHECK-NEXT: 134 +// CHECK-NEXT: 135 +// CHECK-NEXT: 136 +// CHECK-NEXT: 137 +// CHECK-NEXT: 138 +// CHECK-NEXT: 139 +// CHECK-NEXT: 140 +// CHECK-NEXT: 141 +// CHECK-NEXT: 142 +// CHECK-NEXT: 143 +// CHECK-NEXT: 144 +// CHECK-NEXT: 145 +// CHECK-NEXT: 146 +// CHECK-NEXT: 147 +// CHECK-NEXT: 148 +// CHECK-NEXT: 149 +// CHECK-NEXT: 150 +// CHECK-NEXT: 151 +// CHECK-NEXT: 152 +// CHECK-NEXT: 153 +// CHECK-NEXT: 154 +// CHECK-NEXT: 155 +// CHECK-NEXT: 156 +// CHECK-NEXT: 157 +// CHECK-NEXT: 158 +// CHECK-NEXT: 159 +// CHECK-NEXT: 160 +// CHECK-NEXT: 161 +// CHECK-NEXT: 162 +// CHECK-NEXT: 163 +// CHECK-NEXT: 164 +// CHECK-NEXT: 165 +// CHECK-NEXT: 166 +// CHECK-NEXT: 167 +// CHECK-NEXT: 168 +// CHECK-NEXT: 169 +// CHECK-NEXT: 170 +// CHECK-NEXT: 171 +// CHECK-NEXT: 172 +// CHECK-NEXT: 173 +// CHECK-NEXT: 174 +// CHECK-NEXT: 175 +// CHECK-NEXT: 176 +// CHECK-NEXT: 177 +// CHECK-NEXT: 178 +// CHECK-NEXT: 179 +// CHECK-NEXT: 180 +// CHECK-NEXT: 181 +// CHECK-NEXT: 182 +// CHECK-NEXT: 183 +// CHECK-NEXT: 184 +// CHECK-NEXT: 185 +// CHECK-NEXT: 186 +// CHECK-NEXT: 187 +// CHECK-NEXT: 188 +// CHECK-NEXT: 189 +// CHECK-NEXT: 190 +// CHECK-NEXT: 191 +// CHECK-NEXT: 192 +// CHECK-NEXT: 193 +// CHECK-NEXT: 194 +// CHECK-NEXT: 195 +// CHECK-NEXT: 196 +// CHECK-NEXT: 197 +// CHECK-NEXT: 198 +// CHECK-NEXT: 199 +// CHECK-NEXT: 200 +// CHECK-NEXT: 201 +// CHECK-NEXT: 202 +// CHECK-NEXT: 203 +// CHECK-NEXT: 204 +// CHECK-NEXT: 205 +// CHECK-NEXT: 206 +// CHECK-NEXT: 207 +// CHECK-NEXT: 208 +// CHECK-NEXT: 209 +// CHECK-NEXT: 210 +// CHECK-NEXT: 211 +// CHECK-NEXT: 212 +// CHECK-NEXT: 213 +// CHECK-NEXT: 214 +// CHECK-NEXT: 215 +// CHECK-NEXT: 216 +// CHECK-NEXT: 217 +// CHECK-NEXT: 218 +// CHECK-NEXT: 219 +// CHECK-NEXT: 220 +// CHECK-NEXT: 221 +// CHECK-NEXT: 222 +// CHECK-NEXT: 223 +// CHECK-NEXT: 224 +// CHECK-NEXT: 225 +// CHECK-NEXT: 226 +// CHECK-NEXT: 227 +// CHECK-NEXT: 228 +// CHECK-NEXT: 229 +// CHECK-NEXT: 230 +// CHECK-NEXT: 231 +// CHECK-NEXT: 232 +// CHECK-NEXT: 233 +// CHECK-NEXT: 234 +// CHECK-NEXT: 235 +// CHECK-NEXT: 236 +// CHECK-NEXT: 237 +// CHECK-NEXT: 238 +// CHECK-NEXT: 239 +// CHECK-NEXT: 240 +// CHECK-NEXT: 241 +// CHECK-NEXT: 242 +// CHECK-NEXT: 243 +// CHECK-NEXT: 244 +// CHECK-NEXT: 245 +// CHECK-NEXT: 246 +// CHECK-NEXT: 247 +// CHECK-NEXT: 248 +// CHECK-NEXT: 249 +// CHECK-NEXT: 250 +// CHECK-NEXT: 251 +// CHECK-NEXT: 252 +// CHECK-NEXT: 253 +// CHECK-NEXT: 254 + +package main + +func testBasics() { + var i [2]int + j := &i + i[0] = 123 + i[1] = 456 + println(i[0], i[1]) + println(j[0], j[1]) + i[0]++ + i[1]-- + println(i[0], i[1]) + println(j[0], j[1]) +} + +func testByteIndex() { + var a [255]int + for i := 0; i < len(a); i++ { + a[i] = i + } + for i := byte(0); i < byte(len(a)); i++ { + println(a[i]) + } +} + +func main() { + //testBasics() + testByteIndex() +} diff --git a/llgo/test/execution/arrays/range.go b/llgo/test/execution/arrays/range.go new file mode 100644 index 00000000000..37d22f62bda --- /dev/null +++ b/llgo/test/execution/arrays/range.go @@ -0,0 +1,23 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 0 0 +// CHECK-NEXT: 1 1 1 +// CHECK-NEXT: 2 2 2 +// CHECK-NEXT: 3 0 0 +// CHECK-NEXT: 4 4 4 +// CHECK-NEXT: 0 10 +// CHECK-NEXT: 1 20 +// CHECK-NEXT: 2 30 + +package main + +func main() { + a := [...]int{1: 1, 2: 2, 4: 4} + for i, val := range a { + println(i, val, a[i]) + } + for i, val := range [...]int{10, 20, 30} { + println(i, val) + } +} diff --git a/llgo/test/execution/arrays/slice.go b/llgo/test/execution/arrays/slice.go new file mode 100644 index 00000000000..e2880906d92 --- /dev/null +++ b/llgo/test/execution/arrays/slice.go @@ -0,0 +1,14 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 10 +// CHECK-NEXT: 9 + +package main + +func main() { + var a [10]int + b := a[1:] + println(len(a)) + println(len(b)) +} diff --git a/llgo/test/execution/assignment/arrays.go b/llgo/test/execution/assignment/arrays.go new file mode 100644 index 00000000000..30921a4cabd --- /dev/null +++ b/llgo/test/execution/assignment/arrays.go @@ -0,0 +1,22 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: +1.000000e+000 +// CHECK-NEXT: +2.000000e+000 +// CHECK-NEXT: +3.000000e+000 + +package main + +var a1 = [...]float32{1.0, 2.0, 3.0} + +func main() { + var a2 [3]float32 + a2 = a1 + println(a2[0]) + println(a2[1]) + println(a2[2]) + + // broken due to lack of promotion of + // stack to heap. + //println(a2[0], a2[1], a2[2]) +} diff --git a/llgo/test/execution/assignment/binop.go b/llgo/test/execution/assignment/binop.go new file mode 100644 index 00000000000..51793ff4c5c --- /dev/null +++ b/llgo/test/execution/assignment/binop.go @@ -0,0 +1,21 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 246 +// CHECK-NEXT: 123 +// CHECK-NEXT: 124 +// CHECK-NEXT: 123 + +package main + +func main() { + x := 123 + x *= 2 + println(x) + x /= 2 + println(x) + x += 1 + println(x) + x -= 1 + println(x) +} diff --git a/llgo/test/execution/assignment/dereferencing.go b/llgo/test/execution/assignment/dereferencing.go new file mode 100644 index 00000000000..607e28d5909 --- /dev/null +++ b/llgo/test/execution/assignment/dereferencing.go @@ -0,0 +1,13 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 123 + +package main + +func main() { + var x int + px := &x + *px = 123 + println(x) +} diff --git a/llgo/test/execution/assignment/multi.go b/llgo/test/execution/assignment/multi.go new file mode 100644 index 00000000000..60b8805debf --- /dev/null +++ b/llgo/test/execution/assignment/multi.go @@ -0,0 +1,40 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 123 456 +// CHECK-NEXT: 456 123 +// CHECK-NEXT: 456 123 +// CHECK-NEXT: 123 456 +// CHECK-NEXT: 123 456 + +package main + +func xyz() (int, int) { + return 123, 456 +} + +func abc() (int, int) { + var a, b = xyz() + return a, b +} + +type S struct { + a int + b int +} + +func main() { + a, b := xyz() + println(a, b) + b, a = abc() + println(a, b) + + // swap + println(a, b) + a, b = b, a + println(a, b) + + var s S + s.a, s.b = a, b + println(s.a, s.b) +} diff --git a/llgo/test/execution/assignment/namedresult.go b/llgo/test/execution/assignment/namedresult.go new file mode 100644 index 00000000000..daf9b003c61 --- /dev/null +++ b/llgo/test/execution/assignment/namedresult.go @@ -0,0 +1,42 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 123 +// CHECK-NEXT: 456 +// CHECK-NEXT: 1 2 +// CHECK-NEXT: 666 0 + +package main + +func f1() (x int) { + x = 123 + return +} + +func f2() (x int) { + return 456 +} + +func f3() (x, y int) { + y, x = 2, 1 + return +} + +func f4() (x, _ int) { + x = 666 + return +} + +func main() { + x := f1() + println(x) + x = f2() + println(x) + + var y int + x, y = f3() + println(x, y) + + x, y = f4() + println(x, y) +} diff --git a/llgo/test/execution/branching/goto.go b/llgo/test/execution/branching/goto.go new file mode 100644 index 00000000000..748c666da42 --- /dev/null +++ b/llgo/test/execution/branching/goto.go @@ -0,0 +1,43 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 5 +// CHECK-NEXT: 6 +// CHECK-NEXT: 7 +// CHECK-NEXT: 8 +// CHECK-NEXT: 9 +// CHECK-NEXT: done +// CHECK-NEXT: ! + +package main + +func f1() { + goto labeled +labeled: + goto done + return +done: + println("!") +} + +func main() { + i := 0 +start: + if i < 10 { + println(i) + i++ + goto start + } else { + goto end + } + return +end: + println("done") + f1() + return +} diff --git a/llgo/test/execution/branching/labeled.go b/llgo/test/execution/branching/labeled.go new file mode 100644 index 00000000000..efff5ef1d21 --- /dev/null +++ b/llgo/test/execution/branching/labeled.go @@ -0,0 +1,22 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 + +package main + +func labeledBreak() { + var i int +L: + for ; i < 10; i++ { + switch { + default: + break L + } + } + println(i) +} + +func main() { + labeledBreak() +} diff --git a/llgo/test/execution/chan/buffered.go b/llgo/test/execution/chan/buffered.go new file mode 100644 index 00000000000..9247ce32e04 --- /dev/null +++ b/llgo/test/execution/chan/buffered.go @@ -0,0 +1,41 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 0 +// CHECK-NEXT: 0 1 +// CHECK-NEXT: 10 +// CHECK-NEXT: 20 +// CHECK-NEXT: 30 +// CHECK-NEXT: 40 +// CHECK-NEXT: 50 +// CHECK-NEXT: 60 +// CHECK-NEXT: 70 +// CHECK-NEXT: 80 +// CHECK-NEXT: 90 +// CHECK-NEXT: 100 +// CHECK-NEXT: -1 + +package main + +func main() { + c := make(chan int) + println(len(c), cap(c)) + c1 := make(chan int, 1) + println(len(c1), cap(c1)) + f := func() { + n, ok := <-c + if ok { + c1 <- n * 10 + } else { + c1 <- -1 + } + } + for i := 0; i < 10; i++ { + go f() + c <- i + 1 + println(<-c1) + } + go f() + close(c) + println(<-c1) +} diff --git a/llgo/test/execution/chan/range.go b/llgo/test/execution/chan/range.go new file mode 100644 index 00000000000..eeaedb7f982 --- /dev/null +++ b/llgo/test/execution/chan/range.go @@ -0,0 +1,28 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 5 +// CHECK-NEXT: 6 +// CHECK-NEXT: 7 +// CHECK-NEXT: 8 +// CHECK-NEXT: 9 + +package main + +func main() { + ch := make(chan int) + go func() { + for i := 0; i < 10; i++ { + ch <- i + } + close(ch) + }() + for n := range ch { + println(n) + } +} diff --git a/llgo/test/execution/chan/select.go b/llgo/test/execution/chan/select.go new file mode 100644 index 00000000000..80872f578ce --- /dev/null +++ b/llgo/test/execution/chan/select.go @@ -0,0 +1,27 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: sent a value +// CHECK-NEXT: received 123 +// CHECK-NEXT: default + +package main + +func f1() { + c := make(chan int, 1) + for i := 0; i < 3; i++ { + select { + case n, _ := <-c: + println("received", n) + c = nil + case c <- 123: + println("sent a value") + default: + println("default") + } + } +} + +func main() { + f1() +} diff --git a/llgo/test/execution/chan/self.go b/llgo/test/execution/chan/self.go new file mode 100644 index 00000000000..d26ee4a22f3 --- /dev/null +++ b/llgo/test/execution/chan/self.go @@ -0,0 +1,20 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: true + +package main + +func main() { + ch := make(chan int, uint8(1)) + + ch <- 1 + println(<-ch) + + ch <- 2 + x, ok := <-ch + println(x) + println(ok) +} diff --git a/llgo/test/execution/circulartype.go b/llgo/test/execution/circulartype.go new file mode 100644 index 00000000000..01e9ce44493 --- /dev/null +++ b/llgo/test/execution/circulartype.go @@ -0,0 +1,17 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | count 0 + +package main + +type A struct { + b1, b2 B +} + +type B struct { + a1, a2 *A +} + +func main() { + var a A + _ = a +} diff --git a/llgo/test/execution/closures/basic.go b/llgo/test/execution/closures/basic.go new file mode 100644 index 00000000000..2a84fc130e8 --- /dev/null +++ b/llgo/test/execution/closures/basic.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: abc + +package main + +func cat(a, b string) func(string) string { + return func(c string) string { return a + b + c } +} + +func main() { + f := cat("a", "b") + println(f("c")) +} diff --git a/llgo/test/execution/closures/issue176.go b/llgo/test/execution/closures/issue176.go new file mode 100644 index 00000000000..4a505ca19b0 --- /dev/null +++ b/llgo/test/execution/closures/issue176.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: false + +package main + +func main() { + a := false + f := func() { + make(chan *bool, 1) <- &a + } + f() + println(a) +} diff --git a/llgo/test/execution/complex.go b/llgo/test/execution/complex.go new file mode 100644 index 00000000000..ad2a87bbd3c --- /dev/null +++ b/llgo/test/execution/complex.go @@ -0,0 +1,24 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: (+1.000000e+000+2.000000e+000i) +// CHECK-NEXT: (-1.000000e+000-2.000000e+000i) +// CHECK-NEXT: true +// CHECK-NEXT: (+1.000000e+000+2.000000e+000i) +// CHECK-NEXT: (-1.000000e+000-2.000000e+000i) +// CHECK-NEXT: true + +package main + +func main() { + var f32 float32 = 1 + var f64 float64 = 1 + c64 := complex(f32, f32+1) + println(c64) + println(-c64) + println(c64 == c64) + c128 := complex(f64, f64+1) + println(c128) + println(-c128) + println(c128 == c128) +} diff --git a/llgo/test/execution/const.go b/llgo/test/execution/const.go new file mode 100644 index 00000000000..45dbb0f03cd --- /dev/null +++ b/llgo/test/execution/const.go @@ -0,0 +1,78 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 1 1 +// CHECK-NEXT: 1 1 1 4 +// CHECK-NEXT: 2147483647 +// CHECK-NEXT: -2147483648 +// CHECK-NEXT: 2147483647 +// CHECK-NEXT: -127 +// CHECK-NEXT: false +// CHECK-NEXT: 10000000000 +// CHECK-NEXT: 1 +// CHECK-NEXT: 3 + +package main + +import "runtime" + +const ( + a = iota * 2 + A = 1 + B + C + D = Z + iota +) + +const ( + Z = iota + Big = 1<<31 - 1 + Big2 = -2147483648 + Big3 = 2147483647 +) + +const ( + expbits32 uint = 8 + bias32 = -1<<(expbits32-1) + 1 + darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" +) + +func f1() float32 { + return 0 +} + +func constArrayLen() { + a := [...]int{1, 2, 3} + const x = len(a) + println(x) +} + +func main() { + println(a) + println(B) + println(A, A) + println(A, B, C, D) + println(Big) + println(Big2) + println(Big3) + println(bias32) + + // Currently fails, due to difference in C printf and Go's println + // formatting of the exponent. + //println(10 * 1e9) + println(darwinAMD64) + + // Test conversion. + println(int64(10) * 1e9) + + // Ensure consts work just as well when declared inside a function. + const ( + x_ = iota + y_ + ) + println(y_) + + constArrayLen() +} diff --git a/llgo/test/execution/conversions/complex.go b/llgo/test/execution/conversions/complex.go new file mode 100644 index 00000000000..91dd366c434 --- /dev/null +++ b/llgo/test/execution/conversions/complex.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | count 0 + +package main + +func constIntToComplex() complex128 { + return 0 +} + +func main() { + var c64 complex64 + var c128 complex128 + c128 = complex128(c64) + c64 = complex64(c128) +} diff --git a/llgo/test/execution/conversions/float.go b/llgo/test/execution/conversions/float.go new file mode 100644 index 00000000000..def11d1699a --- /dev/null +++ b/llgo/test/execution/conversions/float.go @@ -0,0 +1,103 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: -123 +// CHECK-NEXT: -123 +// CHECK-NEXT: -123 +// CHECK-NEXT: -123 +// CHECK-NEXT: 133 +// CHECK-NEXT: 65413 +// CHECK-NEXT: 4294967173 +// CHECK-NEXT: 18446744073709551493 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: 123 +// CHECK-NEXT: -123 +// CHECK-NEXT: -123 +// CHECK-NEXT: -123 +// CHECK-NEXT: -123 +// CHECK-NEXT: 133 +// CHECK-NEXT: 65413 +// CHECK-NEXT: 4294967173 +// CHECK-NEXT: 18446744073709551493 +// CHECK-NEXT: +1.230000e+002 +// CHECK-NEXT: +1.230000e+002 +// CHECK-NEXT: +1.230000e+002 +// CHECK-NEXT: +1.230000e+002 +// CHECK-NEXT: +1.234500e+004 +// CHECK-NEXT: +1.234500e+004 +// CHECK-NEXT: +1.234500e+004 +// CHECK-NEXT: +1.234500e+004 +// CHECK-NEXT: +1.234560e+005 +// CHECK-NEXT: +1.234560e+005 +// CHECK-NEXT: +1.234560e+005 +// CHECK-NEXT: +1.234560e+005 +// CHECK-NEXT: +1.234568e+010 +// CHECK-NEXT: +1.234568e+010 +// CHECK-NEXT: +1.234568e+010 +// CHECK-NEXT: +1.234568e+010 + +package main + +func main() { + // float to int + for _, f32 := range []float32{123.456, -123.456} { + println(int8(f32)) + println(int16(f32)) + println(int32(f32)) + println(int64(f32)) + println(uint8(f32)) + println(uint16(f32)) + println(uint32(f32)) + println(uint64(f32)) + } + for _, f64 := range []float64{123.456, -123.456} { + println(int8(f64)) + println(int16(f64)) + println(int32(f64)) + println(int64(f64)) + println(uint8(f64)) + println(uint16(f64)) + println(uint32(f64)) + println(uint64(f64)) + } + + // int to float + var i8 int8 = 123 + println(float32(i8)) + println(float64(i8)) + var ui8 uint8 = 123 + println(float32(ui8)) + println(float64(ui8)) + var i16 int32 = 12345 + println(float32(i16)) + println(float64(i16)) + var ui16 uint32 = 12345 + println(float32(ui16)) + println(float64(ui16)) + var i32 int32 = 123456 + println(float32(i32)) + println(float64(i32)) + var ui32 uint32 = 123456 + println(float32(ui32)) + println(float64(ui32)) + var i64 int64 = 12345678910 + println(float32(i64)) + println(float64(i64)) + var ui64 uint64 = 12345678910 + println(float32(ui64)) + println(float64(ui64)) +} diff --git a/llgo/test/execution/conversions/int.go b/llgo/test/execution/conversions/int.go new file mode 100644 index 00000000000..092003b3b89 --- /dev/null +++ b/llgo/test/execution/conversions/int.go @@ -0,0 +1,44 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 2147483647 +// CHECK-NEXT: 2147483647 +// CHECK-NEXT: 2147483647 +// CHECK-NEXT: 2147483648 +// CHECK-NEXT: -2147483648 +// CHECK-NEXT: 18446744071562067968 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: -1 +// CHECK-NEXT: 4294967295 +// CHECK-NEXT: 4294967295 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 1 +// CHECK-NEXT: 1 + +package main + +func signed(i32 int32) { + println(uint32(i32)) + println(int64(i32)) + println(uint64(i32)) +} + +func unsigned(u32 uint32) { + println(int32(u32)) + println(int64(u32)) + println(uint64(u32)) +} + +func main() { + signed(1<<31 - 1) + signed(-1 << 31) + signed(0) + unsigned(1<<32 - 1) + unsigned(0) + unsigned(1) +} diff --git a/llgo/test/execution/conversions/sameunderlying.go b/llgo/test/execution/conversions/sameunderlying.go new file mode 100644 index 00000000000..8208cfba116 --- /dev/null +++ b/llgo/test/execution/conversions/sameunderlying.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | count 0 + +package main + +type X struct{} +type Y X + +func main() { + var x X + px := &x + py := (*Y)(&x) + py = (*Y)(px) + _ = py +} diff --git a/llgo/test/execution/defer.go b/llgo/test/execution/defer.go new file mode 100644 index 00000000000..ba1b63217b8 --- /dev/null +++ b/llgo/test/execution/defer.go @@ -0,0 +1,125 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: f2.1 +// CHECK-NEXT: f5 +// CHECK-NEXT: recovered no error +// CHECK-NEXT: f5 +// CHECK-NEXT: recovered: meep meep +// CHECK-NEXT: 888 +// CHECK-NEXT: f5 +// CHECK-NEXT: recovered no error +// CHECK-NEXT: f5 +// CHECK-NEXT: recovered no error +// CHECK-NEXT: 888 +// CHECK-NEXT: 456 +// CHECK-NEXT: 999 +// CHECK-NEXT: 999 +// CHECK-NEXT: 123 +// CHECK-NEXT: 999 +// CHECK-NEXT: 999 +// CHECK-NEXT: 246 +// CHECK-NEXT: f2.2 +// CHECK-NEXT: f2.3 +// CHECK-NEXT: f1.1 +// CHECK-NEXT: f1.2 +// CHECK-NEXT: recovered: second +// CHECK-NEXT: ahoy + +package main + +type T struct { + value int +} + +type T1 struct { + T +} + +func (t T) abc() { + println(t.value) +} + +func (t *T) def() { + println(t.value) +} + +func (t *T) ghi(v int) { + println(v) +} + +func printerr(err interface{}) { + if err != nil { + println("recovered:", err.(string)) + } else { + println("recovered no error") + } +} + +func f6() { + defer func() { printerr(recover()) }() + defer func() { panic("second") }() + panic("first") +} + +func f5(panic_ bool) { + var t1 T1 + t1.T.value = 888 + defer t1.abc() + var f func(int) + f = func(recursion int) { + if recursion > 0 { + f(recursion - 1) + return + } + println("f5") + printerr(recover()) + } + defer f(0) // will recover (after f(1)) + defer f(1) // won't recover + if panic_ { + panic("meep meep") + } +} + +func f4() { + var a T = T{999} + var b *T = &a + defer a.abc() + defer a.def() + defer a.ghi(123) + defer b.abc() + defer b.def() + defer b.ghi(456) + f5(true) + f5(false) // verify the recover in f5 works +} + +func f3() (a int) { + defer func() { a *= 2 }() + f4() + return 123 +} + +func f2() { + defer func() { println("f2.3") }() + defer func(s string) { println(s) }("f2.2") + println("f2.1") + println(f3()) +} + +func f1() { + defer func() { println("f1.2") }() + defer func() { println("f1.1") }() + f2() +} + +func builtins() { + defer println("ahoy") +} + +func main() { + f1() + f6() + builtins() +} diff --git a/llgo/test/execution/errors/recover.go b/llgo/test/execution/errors/recover.go new file mode 100644 index 00000000000..70ee2ac15a7 --- /dev/null +++ b/llgo/test/execution/errors/recover.go @@ -0,0 +1,11 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: (0x0,0x0) + +package main + +func main() { + err := recover() + println(err) +} diff --git a/llgo/test/execution/for/branch.go b/llgo/test/execution/for/branch.go new file mode 100644 index 00000000000..5484c891adf --- /dev/null +++ b/llgo/test/execution/for/branch.go @@ -0,0 +1,41 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 0 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 + +package main + +func main() { + for i := 0; true; i++ { + println(i) + if i == 2 { + println(3) + break + } + println(1) + i++ + continue + println("unreachable") + } + + nums := [...]int{0, 1, 2, 3, 4, 5} + for n := range nums { + if n == 1 { + continue + } + println(n) + if n == 4 { + { + break + } + println("!") + } + } +} diff --git a/llgo/test/execution/fun.go b/llgo/test/execution/fun.go new file mode 100644 index 00000000000..c70fe69172d --- /dev/null +++ b/llgo/test/execution/fun.go @@ -0,0 +1,28 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 246 +// CHECK-NEXT: 123 true false + +// vim: set ft=go : + +package main + +func test() func() int { + return blah +} + +func blah() int { + return 123 +} + +func sret() (int, bool, bool) { + return 123, true, false +} + +func main() { + f := test() + println(2 * f()) + a, b, c := sret() + println(a, b, c) +} diff --git a/llgo/test/execution/functions/compare.go b/llgo/test/execution/functions/compare.go new file mode 100644 index 00000000000..9daa062efe9 --- /dev/null +++ b/llgo/test/execution/functions/compare.go @@ -0,0 +1,26 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: true + +package main + +func main() { + var f func() + println(f == nil) + println(f != nil) + println(nil == f) + println(nil != f) + f = func() {} + println(f == nil) + println(f != nil) + println(nil == f) + println(nil != f) +} diff --git a/llgo/test/execution/functions/multivalue.go b/llgo/test/execution/functions/multivalue.go new file mode 100644 index 00000000000..a3ce79b3fc0 --- /dev/null +++ b/llgo/test/execution/functions/multivalue.go @@ -0,0 +1,28 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 +// CHECK-NEXT: 20 +// CHECK-NEXT: extra: 10 + +package main + +func swap(a, b int) (int, int) { + return b, a +} + +func sub(a, b int) int { + return a - b +} + +func printint(a int, extra ...int) { + println(a) + for _, b := range extra { + println("extra:", b) + } +} + +func main() { + println(sub(swap(1, 2))) + printint(swap(10, 20)) +} diff --git a/llgo/test/execution/functions/unreachable.go b/llgo/test/execution/functions/unreachable.go new file mode 100644 index 00000000000..436012c4e41 --- /dev/null +++ b/llgo/test/execution/functions/unreachable.go @@ -0,0 +1,53 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: f1 +// CHECK-NEXT: f2 +// CHECK-NEXT: f3 +// CHECK-NEXT: f4 +// CHECK-NEXT: 123 + +package main + +func f1() { + if true { + println("f1") + return + } + for { + } +} + +func f2() { + defer func() { println("f2") }() + if true { + return + } + for { + } +} + +func f3() int { + if true { + println("f3") + return 123 + } + for { + } +} + +func f4() int { + defer func() { println("f4") }() + if true { + return 123 + } + for { + } +} + +func main() { + f1() + f2() + f3() + println(f4()) +} diff --git a/llgo/test/execution/go.go b/llgo/test/execution/go.go new file mode 100644 index 00000000000..2bfe775ff92 --- /dev/null +++ b/llgo/test/execution/go.go @@ -0,0 +1,34 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: hello from T 1 +// CHECK-NEXT: hello from T 2 + +package main + +type T struct { + val int +} + +func (t T) Hello(done chan bool) { + println("hello from T", t.val) + done <- true +} + +type I interface { + Hello(chan bool) +} + +func main() { + done := make(chan bool) + + t := T{1} + go t.Hello(done) + <-done + + var i I = T{2} + go i.Hello(done) + <-done + + go println("hello builtin") +} diff --git a/llgo/test/execution/if/lazy.go b/llgo/test/execution/if/lazy.go new file mode 100644 index 00000000000..5171a774fa9 --- /dev/null +++ b/llgo/test/execution/if/lazy.go @@ -0,0 +1,46 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: False() +// CHECK-NEXT: False() +// CHECK-NEXT: false +// CHECK-NEXT: False() +// CHECK-NEXT: True() +// CHECK-NEXT: true +// CHECK-NEXT: True() +// CHECK-NEXT: true +// CHECK-NEXT: True() +// CHECK-NEXT: true +// CHECK-NEXT: False() +// CHECK-NEXT: false +// CHECK-NEXT: False() +// CHECK-NEXT: false +// CHECK-NEXT: True() +// CHECK-NEXT: False() +// CHECK-NEXT: false +// CHECK-NEXT: True() +// CHECK-NEXT: True() +// CHECK-NEXT: true + +package main + +func False() bool { + println("False()") + return false +} + +func True() bool { + println("True()") + return true +} + +func main() { + println(False() || False()) + println(False() || True()) + println(True() || False()) + println(True() || True()) + println(False() && False()) + println(False() && True()) + println(True() && False()) + println(True() && True()) +} diff --git a/llgo/test/execution/init.go b/llgo/test/execution/init.go new file mode 100644 index 00000000000..46c7fa16212 --- /dev/null +++ b/llgo/test/execution/init.go @@ -0,0 +1,17 @@ +// RUN: llgo -o %t %s %p/Inputs/init2.go +// RUN: %t 2>&1 | FileCheck %s + +package main + +// CHECK-DAG: do some other stuff before main +//func init() + +// CHECK-DAG: do some stuff before main +func init() { + println("do some stuff before main") +} + +// CHECK: main has been called +func main() { + println("main has been called") +} 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() +} diff --git a/llgo/test/execution/literals/array.go b/llgo/test/execution/literals/array.go new file mode 100644 index 00000000000..975ec02760f --- /dev/null +++ b/llgo/test/execution/literals/array.go @@ -0,0 +1,78 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 9223372036854775808 -63 false +// CHECK-NEXT: 11529215046068469760 -60 false +// CHECK-NEXT: 14411518807585587200 -57 false +// CHECK-NEXT: 18014398509481984000 -54 false +// CHECK-NEXT: 11258999068426240000 -50 false +// CHECK-NEXT: 14073748835532800000 -47 false +// CHECK-NEXT: 17592186044416000000 -44 false +// CHECK-NEXT: 10995116277760000000 -40 false +// CHECK-NEXT: 0 0 +// CHECK-NEXT: 1 0 +// CHECK-NEXT: 2 1 +// CHECK-NEXT: 3 0 +// CHECK-NEXT: 4 2 +// CHECK-NEXT: 5 0 +// CHECK-NEXT: 6 3 +// CHECK-NEXT: 7 0 +// CHECK-NEXT: 8 4 +// CHECK-NEXT: 9 0 +// CHECK-NEXT: 0 1 +// CHECK-NEXT: 1 2 + +package main + +// An extFloat represents an extended floating-point number, with more +// precision than a float64. It does not try to save bits: the +// number represented by the structure is mant*(2^exp), with a negative +// sign if neg is true. +type extFloat struct { + mant uint64 + exp int + neg bool +} + +var smallPowersOfTen = [...]extFloat{ + {1 << 63, -63, false}, // 1 + {0xa << 60, -60, false}, // 1e1 + {0x64 << 57, -57, false}, // 1e2 + {0x3e8 << 54, -54, false}, // 1e3 + {0x2710 << 50, -50, false}, // 1e4 + {0x186a0 << 47, -47, false}, // 1e5 + {0xf4240 << 44, -44, false}, // 1e6 + {0x989680 << 40, -40, false}, // 1e7 +} + +var arrayWithHoles = [10]int{ + 2: 1, + 4: 2, + 6: 3, + 8: 4, +} + +type namedInt int32 + +const N0 namedInt = 0 +const N1 namedInt = 1 + +var arrayWithNamedIndices = [...]int{ + N0: 1, + N1: 2, +} + +func main() { + for i := range smallPowersOfTen { + s := smallPowersOfTen[i] + println(s.mant, s.exp, s.neg) + } + + for i, value := range arrayWithHoles { + println(i, value) + } + + for i, value := range arrayWithNamedIndices { + println(i, value) + } +} diff --git a/llgo/test/execution/literals/func.go b/llgo/test/execution/literals/func.go new file mode 100644 index 00000000000..b8dbef340fa --- /dev/null +++ b/llgo/test/execution/literals/func.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false + +package main + +func main() { + f := func(x bool) { + println(x) + } + f(true) + f(false) +} diff --git a/llgo/test/execution/literals/map.go b/llgo/test/execution/literals/map.go new file mode 100644 index 00000000000..32173f50d93 --- /dev/null +++ b/llgo/test/execution/literals/map.go @@ -0,0 +1,24 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: false +// CHECK-NEXT: 2 +// CHECK-NEXT: 1 0 3 +// CHECK-NEXT: 0.1 +// CHECK-NEXT: 0.2 +// CHECK-NEXT: 0.3 + +package main + +func main() { + type IntMap map[int]int + m := IntMap{0: 1, 2: 3} + println(m == nil) + println(len(m)) + println(m[0], m[1], m[2]) + + f32tostr := map[float32]string{0.1: "0.1", 0.2: "0.2", 0.3: "0.3"} + println(f32tostr[0.1]) + println(f32tostr[0.2]) + println(f32tostr[0.3]) +} diff --git a/llgo/test/execution/literals/slice.go b/llgo/test/execution/literals/slice.go new file mode 100644 index 00000000000..dbb02bff718 --- /dev/null +++ b/llgo/test/execution/literals/slice.go @@ -0,0 +1,21 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: abc +// CHECK-NEXT: 123 +// CHECK-NEXT: abc +// CHECK-NEXT: 123 + +package main + +func main() { + x := []string{"abc", "123"} + println(x[0]) + println(x[1]) + + // Elements are composite literals, so the '&' can be elided. + type S struct{ string } + y := []*S{{"abc"}, {"123"}} + println(y[0].string) + println(y[1].string) +} diff --git a/llgo/test/execution/literals/struct.go b/llgo/test/execution/literals/struct.go new file mode 100644 index 00000000000..4fede950784 --- /dev/null +++ b/llgo/test/execution/literals/struct.go @@ -0,0 +1,62 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 2 +// CHECK-NEXT: 1 2 +// CHECK-NEXT: 0 1 2 +// CHECK-NEXT: 1 2 +// CHECK-NEXT: 3 4 + +package main + +type E struct { + e *E +} + +type S struct { + *E + a, b int +} + +type File struct { +} + +type Reader struct { +} + +type Response struct { +} + +type reader struct { + *Reader + fd *File + resp *Response +} + +type Range32 struct { + Lo uint32 + Hi uint32 + Stride uint32 +} + +func main() { + s := &S{nil, 1, 2} + println(s.a, s.b) + s = &S{a: 1, b: 2} + println(s.a, s.b) + + _ = &reader{} + + r := Range32{ + Lo: 0, + Stride: 2, + Hi: 1, + } + println(r.Lo, r.Hi, r.Stride) + + // slice of structs + ss := []S{{nil, 1, 2}, {nil, 3, 4}} + for _, s := range ss { + println(s.a, s.b) + } +} diff --git a/llgo/test/execution/maps/delete.go b/llgo/test/execution/maps/delete.go new file mode 100644 index 00000000000..6879974e9c9 --- /dev/null +++ b/llgo/test/execution/maps/delete.go @@ -0,0 +1,19 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 +// CHECK-NEXT: 1 1 +// CHECK-NEXT: 0 0 + +package main + +func main() { + m := make(map[int]int) + delete(m, 0) // no-op + m[0] = 1 + println(len(m)) + delete(m, 1) // no-op + println(len(m), m[0]) + delete(m, 0) // delete element in map + println(len(m), m[0]) +} diff --git a/llgo/test/execution/maps/insert.go b/llgo/test/execution/maps/insert.go new file mode 100644 index 00000000000..90b31cc96c1 --- /dev/null +++ b/llgo/test/execution/maps/insert.go @@ -0,0 +1,29 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 456 +// CHECK-NEXT: 1 +// CHECK-NEXT: 789 + +package main + +func main() { + { + var m map[int]int + println(len(m)) // 0 + println(m[123]) // 0, despite map being nil + } + + { + m := make(map[int]int) + m[123] = 456 + println(len(m)) // 1 + println(m[123]) + m[123] = 789 + println(len(m)) // 1 + println(m[123]) + } +} diff --git a/llgo/test/execution/maps/lookup.go b/llgo/test/execution/maps/lookup.go new file mode 100644 index 00000000000..69d28788205 --- /dev/null +++ b/llgo/test/execution/maps/lookup.go @@ -0,0 +1,30 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 false +// CHECK-NEXT: 1 true +// CHECK-NEXT: 1 true +// CHECK-NEXT: 1 true + +package main + +func main() { + m := make(map[int]int) + v, ok := m[8] + println(v, ok) + m[8] = 1 + v, ok = m[8] + println(v, ok) + + type S struct{ s1, s2 string } + sm := make(map[S]int) + sm[S{"ABC", "DEF"}] = 1 + sv, ok := sm[S{string([]byte{65, 66, 67}), string([]byte{68, 69, 70})}] + println(sv, ok) + + type A [2]string + am := make(map[A]int) + am[A{"ABC", "DEF"}] = 1 + av, ok := am[A{string([]byte{65, 66, 67}), string([]byte{68, 69, 70})}] + println(av, ok) +} diff --git a/llgo/test/execution/maps/range.go b/llgo/test/execution/maps/range.go new file mode 100644 index 00000000000..f3dc03fbd9e --- /dev/null +++ b/llgo/test/execution/maps/range.go @@ -0,0 +1,48 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 5 +// CHECK-NEXT: 0 3 +// CHECK-NEXT: 1 4 +// CHECK-NEXT: 2 5 +// CHECK-NEXT: 1 +// CHECK-NEXT: done + +package main + +func main() { + defer println("done") + m := make(map[int]int) + m[0] = 3 + m[1] = 4 + m[2] = 5 + for k := range m { + println(k) + } + for k, _ := range m { + println(k) + } + for _, v := range m { + println(v) + } + for k, v := range m { + println(k, v) + } + + // test deletion. + i := 0 + for k, _ := range m { + i++ + delete(m, (k+1)%3) + delete(m, (k+2)%3) + } + println(i) +} diff --git a/llgo/test/execution/methods/methodvalues.go b/llgo/test/execution/methods/methodvalues.go new file mode 100644 index 00000000000..cf8a980df08 --- /dev/null +++ b/llgo/test/execution/methods/methodvalues.go @@ -0,0 +1,64 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 246 +// CHECK-NEXT: T2.f() +// CHECK-NEXT: 10 +// CHECK-NEXT: abc + +package main + +type T1 struct { + value int +} + +func (t *T1) f(m int) int { + return m * t.value +} + +func f1() { + var t T1 + var f func(int) int = t.f + t.value = 2 + println(f(123)) +} + +type T2 struct{} + +func (T2) f() { + println("T2.f()") +} + +func f2() { + var f func() = T2{}.f + f() +} + +type T3 complex128 + +func (t T3) f() int { + return int(real(t)) +} + +func f3() { + var f func() int = T3(10).f + println(f()) +} + +type T4 string + +func (t T4) f() string { + return string(t) +} + +func f4() { + var f func() string = T4("abc").f + println(f()) +} + +func main() { + f1() + f2() + f3() + f4() +} diff --git a/llgo/test/execution/methods/nilrecv.go b/llgo/test/execution/methods/nilrecv.go new file mode 100644 index 00000000000..defe2f43723 --- /dev/null +++ b/llgo/test/execution/methods/nilrecv.go @@ -0,0 +1,31 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false + +package main + +type T1 int + +func (t *T1) t1() { println(t == nil) } + +func constNilRecv() { + (*T1)(nil).t1() +} + +func nonConstNilRecv() { + var v1 T1 + v1.t1() + var v2 *T1 + v2.t1() + v2 = &v1 + v2.t1() +} + +func main() { + constNilRecv() + nonConstNilRecv() +} diff --git a/llgo/test/execution/methods/selectors.go b/llgo/test/execution/methods/selectors.go new file mode 100644 index 00000000000..bcd417366fb --- /dev/null +++ b/llgo/test/execution/methods/selectors.go @@ -0,0 +1,45 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: F1 +// CHECK-NEXT: F2 +// CHECK-NEXT: F1 +// CHECK-NEXT: F2 + +package main + +type S1 struct{} +type S2 struct { + S1 +} + +func (s S1) F1() { + println("F1") +} + +func (s *S2) F2() { + println("F2") +} + +func testUnnamedStructMethods() { + // Test method lookup on an unnamed struct type. + var x struct { + S1 + S2 + } + x.F1() + x.F2() +} + +func main() { + var s S2 + + // Derive pointer-receiver function. + f1 := (*S2).F1 + f1(&s) + + f2 := (*S2).F2 + f2(&s) + + testUnnamedStructMethods() +} diff --git a/llgo/test/execution/new.go b/llgo/test/execution/new.go new file mode 100644 index 00000000000..24773de7f35 --- /dev/null +++ b/llgo/test/execution/new.go @@ -0,0 +1,17 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 2 +// CHECK-NEXT: 4 + +package main + +func main() { + x := new(int) + println(*x) + *x = 2 + println(*x) + *x = *x * *x + println(*x) +} diff --git a/llgo/test/execution/nil.go b/llgo/test/execution/nil.go new file mode 100644 index 00000000000..0aa94e7c0d4 --- /dev/null +++ b/llgo/test/execution/nil.go @@ -0,0 +1,32 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0x0 +// CHECK-NEXT: x is nil +// CHECK-NEXT: y is nil +// CHECK-NEXT: z is nil + +package main + +func main() { + var x *int = nil + println(x) + + if x == nil { + println("x is nil") + } + + var y interface{} + var z interface{} = y + if y == nil { + println("y is nil") + } else { + println("y is not nil") + } + + if z == nil { + println("z is nil") + } else { + println("z is not nil") + } +} diff --git a/llgo/test/execution/operators/basics.go b/llgo/test/execution/operators/basics.go new file mode 100644 index 00000000000..19425868f55 --- /dev/null +++ b/llgo/test/execution/operators/basics.go @@ -0,0 +1,133 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 4096 +// CHECK-NEXT: 256 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 4096 +// CHECK-NEXT: 256 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 65280 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 61184 +// CHECK-NEXT: 65024 +// CHECK-NEXT: 65296 +// CHECK-NEXT: 65281 +// CHECK-NEXT: 61184 +// CHECK-NEXT: 65024 +// CHECK-NEXT: 65296 +// CHECK-NEXT: 65281 +// CHECK-NEXT: -62 +// CHECK-NEXT: -246 +// CHECK-NEXT: +1.224560e+002 +// CHECK-NEXT: 3 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 122 +// CHECK-NEXT: -124 +// CHECK-NEXT: 120 +// CHECK-NEXT: 18446744073709547520 +// CHECK-NEXT: false +// CHECK-NEXT: 2147483648 +// CHECK-NEXT: 9223372036854775808 +// CHECK-NEXT: 2147483648 2147483648 +// CHECK-NEXT: 9223372036854775808 9223372036854775808 + +package main + +import "unsafe" + +var global string + +var hi = 0xFF00 +var lo = 0xFF00 + +// borrowed from math package to avoid dependency on standard library +func float32bits(f float32) uint32 { return *(*uint32)(unsafe.Pointer(&f)) } +func float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) } + +func main() { + println(hi & 0x1000) + println(hi & 0x0100) + println(hi & 0x0010) + println(hi & 0x0001) + println(lo & 0x1000) + println(lo & 0x0100) + println(lo & 0x0010) + println(lo & 0x0001) + println(hi | lo) + println(hi ^ hi) + println(hi ^ lo) + println(lo ^ lo) + println(hi ^ 0x1000) + println(hi ^ 0x0100) + println(hi ^ 0x0010) + println(hi ^ 0x0001) + println(lo ^ 0x1000) + println(lo ^ 0x0100) + println(lo ^ 0x0010) + println(lo ^ 0x0001) + println(-123 >> 1) + println(-123 << 1) + + var f float64 = 123.456 + f-- + println(f) + + // context of '&' op is used to type the untyped lhs + // operand of the shift expression. + shift := uint(2) + println(uint64(0xFFFFFFFF) & (1<<shift - 1)) + println((1<<shift - 1) & uint64(0xFFFFFFFF)) + + // rhs' type is converted lhs' + println(uint32(1) << uint64(2)) + { + var _uint64 uint64 + var _uint uint + x := _uint64 >> (63 - _uint) + if x == 2<<_uint { + println("!") + } + } + + // There was a bug related to compound expressions involving + // multiple binary logical operators. + var a, b, c int + if a == 0 && (b != 0 || c != 0) { + println("!") + } + + var si int = -123 + var ui int = 123 + println(^si) + println(^ui) + println(ui &^ 3) + + // test case from math/modf.go + var x uint64 = 0xFFFFFFFFFFFFFFFF + var e uint = 40 + x &^= 1<<(64-12-e) - 1 + println(x) + + // compare global to non-global + println(new(string) == &global) + + // negative zero + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + f32 = -f32 + f64 = -f64 + c64 = -c64 + c128 = -c128 + println(float32bits(f32)) + println(float64bits(f64)) + println(float32bits(real(c64)), float32bits(imag(c64))) + println(float64bits(real(c128)), float64bits(imag(c128))) +} diff --git a/llgo/test/execution/operators/binary_untyped.go b/llgo/test/execution/operators/binary_untyped.go new file mode 100644 index 00000000000..f152985ffb5 --- /dev/null +++ b/llgo/test/execution/operators/binary_untyped.go @@ -0,0 +1,17 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true + +package main + +func f1(b bool) bool { + return b +} + +func main() { + x := false + y := x + x = !y + println(x || y) +} diff --git a/llgo/test/execution/operators/shifts.go b/llgo/test/execution/operators/shifts.go new file mode 100644 index 00000000000..728b32b57bf --- /dev/null +++ b/llgo/test/execution/operators/shifts.go @@ -0,0 +1,290 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 4294967295 +// CHECK-NEXT: 4294967295 +// CHECK-NEXT: 2147483647 +// CHECK-NEXT: 4294967294 +// CHECK-NEXT: 1073741823 +// CHECK-NEXT: 4294967292 +// CHECK-NEXT: 536870911 +// CHECK-NEXT: 4294967288 +// CHECK-NEXT: 268435455 +// CHECK-NEXT: 4294967280 +// CHECK-NEXT: 134217727 +// CHECK-NEXT: 4294967264 +// CHECK-NEXT: 67108863 +// CHECK-NEXT: 4294967232 +// CHECK-NEXT: 33554431 +// CHECK-NEXT: 4294967168 +// CHECK-NEXT: 16777215 +// CHECK-NEXT: 4294967040 +// CHECK-NEXT: 8388607 +// CHECK-NEXT: 4294966784 +// CHECK-NEXT: 4194303 +// CHECK-NEXT: 4294966272 +// CHECK-NEXT: 2097151 +// CHECK-NEXT: 4294965248 +// CHECK-NEXT: 1048575 +// CHECK-NEXT: 4294963200 +// CHECK-NEXT: 524287 +// CHECK-NEXT: 4294959104 +// CHECK-NEXT: 262143 +// CHECK-NEXT: 4294950912 +// CHECK-NEXT: 131071 +// CHECK-NEXT: 4294934528 +// CHECK-NEXT: 65535 +// CHECK-NEXT: 4294901760 +// CHECK-NEXT: 32767 +// CHECK-NEXT: 4294836224 +// CHECK-NEXT: 16383 +// CHECK-NEXT: 4294705152 +// CHECK-NEXT: 8191 +// CHECK-NEXT: 4294443008 +// CHECK-NEXT: 4095 +// CHECK-NEXT: 4293918720 +// CHECK-NEXT: 2047 +// CHECK-NEXT: 4292870144 +// CHECK-NEXT: 1023 +// CHECK-NEXT: 4290772992 +// CHECK-NEXT: 511 +// CHECK-NEXT: 4286578688 +// CHECK-NEXT: 255 +// CHECK-NEXT: 4278190080 +// CHECK-NEXT: 127 +// CHECK-NEXT: 4261412864 +// CHECK-NEXT: 63 +// CHECK-NEXT: 4227858432 +// CHECK-NEXT: 31 +// CHECK-NEXT: 4160749568 +// CHECK-NEXT: 15 +// CHECK-NEXT: 4026531840 +// CHECK-NEXT: 7 +// CHECK-NEXT: 3758096384 +// CHECK-NEXT: 3 +// CHECK-NEXT: 3221225472 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2147483648 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: 4026531839 +// CHECK-NEXT: 4026531839 +// CHECK-NEXT: 2013265919 +// CHECK-NEXT: 3758096382 +// CHECK-NEXT: 1006632959 +// CHECK-NEXT: 3221225468 +// CHECK-NEXT: 503316479 +// CHECK-NEXT: 2147483640 +// CHECK-NEXT: 251658239 +// CHECK-NEXT: 4294967280 +// CHECK-NEXT: 125829119 +// CHECK-NEXT: 4294967264 +// CHECK-NEXT: 62914559 +// CHECK-NEXT: 4294967232 +// CHECK-NEXT: 31457279 +// CHECK-NEXT: 4294967168 +// CHECK-NEXT: 15728639 +// CHECK-NEXT: 4294967040 +// CHECK-NEXT: 7864319 +// CHECK-NEXT: 4294966784 +// CHECK-NEXT: 3932159 +// CHECK-NEXT: 4294966272 +// CHECK-NEXT: 1966079 +// CHECK-NEXT: 4294965248 +// CHECK-NEXT: 983039 +// CHECK-NEXT: 4294963200 +// CHECK-NEXT: 491519 +// CHECK-NEXT: 4294959104 +// CHECK-NEXT: 245759 +// CHECK-NEXT: 4294950912 +// CHECK-NEXT: 122879 +// CHECK-NEXT: 4294934528 +// CHECK-NEXT: 61439 +// CHECK-NEXT: 4294901760 +// CHECK-NEXT: 30719 +// CHECK-NEXT: 4294836224 +// CHECK-NEXT: 15359 +// CHECK-NEXT: 4294705152 +// CHECK-NEXT: 7679 +// CHECK-NEXT: 4294443008 +// CHECK-NEXT: 3839 +// CHECK-NEXT: 4293918720 +// CHECK-NEXT: 1919 +// CHECK-NEXT: 4292870144 +// CHECK-NEXT: 959 +// CHECK-NEXT: 4290772992 +// CHECK-NEXT: 479 +// CHECK-NEXT: 4286578688 +// CHECK-NEXT: 239 +// CHECK-NEXT: 4278190080 +// CHECK-NEXT: 119 +// CHECK-NEXT: 4261412864 +// CHECK-NEXT: 59 +// CHECK-NEXT: 4227858432 +// CHECK-NEXT: 29 +// CHECK-NEXT: 4160749568 +// CHECK-NEXT: 14 +// CHECK-NEXT: 4026531840 +// CHECK-NEXT: 7 +// CHECK-NEXT: 3758096384 +// CHECK-NEXT: 3 +// CHECK-NEXT: 3221225472 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2147483648 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 +// CHECK-NEXT: -1 +// CHECK-NEXT: -1 +// CHECK-NEXT: -1 +// CHECK-NEXT: -2 +// CHECK-NEXT: -1 +// CHECK-NEXT: -4 +// CHECK-NEXT: -1 +// CHECK-NEXT: -8 +// CHECK-NEXT: -1 +// CHECK-NEXT: -16 +// CHECK-NEXT: -1 +// CHECK-NEXT: -32 +// CHECK-NEXT: -1 +// CHECK-NEXT: -64 +// CHECK-NEXT: -1 +// CHECK-NEXT: -128 +// CHECK-NEXT: -1 +// CHECK-NEXT: -256 +// CHECK-NEXT: -1 +// CHECK-NEXT: -512 +// CHECK-NEXT: -1 +// CHECK-NEXT: -1024 +// CHECK-NEXT: -1 +// CHECK-NEXT: -2048 +// CHECK-NEXT: -1 +// CHECK-NEXT: -4096 +// CHECK-NEXT: -1 +// CHECK-NEXT: -8192 +// CHECK-NEXT: -1 +// CHECK-NEXT: -16384 +// CHECK-NEXT: -1 +// CHECK-NEXT: -32768 +// CHECK-NEXT: -1 +// CHECK-NEXT: -65536 +// CHECK-NEXT: -1 +// CHECK-NEXT: -131072 +// CHECK-NEXT: -1 +// CHECK-NEXT: -262144 +// CHECK-NEXT: -1 +// CHECK-NEXT: -524288 +// CHECK-NEXT: -1 +// CHECK-NEXT: -1048576 +// CHECK-NEXT: -1 +// CHECK-NEXT: -2097152 +// CHECK-NEXT: -1 +// CHECK-NEXT: -4194304 +// CHECK-NEXT: -1 +// CHECK-NEXT: -8388608 +// CHECK-NEXT: -1 +// CHECK-NEXT: -16777216 +// CHECK-NEXT: -1 +// CHECK-NEXT: -33554432 +// CHECK-NEXT: -1 +// CHECK-NEXT: -67108864 +// CHECK-NEXT: -1 +// CHECK-NEXT: -134217728 +// CHECK-NEXT: -1 +// CHECK-NEXT: -268435456 +// CHECK-NEXT: -1 +// CHECK-NEXT: -536870912 +// CHECK-NEXT: -1 +// CHECK-NEXT: -1073741824 +// CHECK-NEXT: -1 +// CHECK-NEXT: -2147483648 +// CHECK-NEXT: -1 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 1 +// CHECK-NEXT: 0 +// CHECK-NEXT: 2 +// CHECK-NEXT: 0 +// CHECK-NEXT: 4 +// CHECK-NEXT: 0 +// CHECK-NEXT: 8 +// CHECK-NEXT: 0 +// CHECK-NEXT: 16 +// CHECK-NEXT: 0 +// CHECK-NEXT: 32 +// CHECK-NEXT: 0 +// CHECK-NEXT: 64 +// CHECK-NEXT: 0 +// CHECK-NEXT: 128 +// CHECK-NEXT: 0 +// CHECK-NEXT: 256 +// CHECK-NEXT: 0 +// CHECK-NEXT: 512 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1024 +// CHECK-NEXT: 0 +// CHECK-NEXT: 2048 +// CHECK-NEXT: 0 +// CHECK-NEXT: 4096 +// CHECK-NEXT: 0 +// CHECK-NEXT: 8192 +// CHECK-NEXT: 0 +// CHECK-NEXT: 16384 +// CHECK-NEXT: 0 +// CHECK-NEXT: 32768 +// CHECK-NEXT: 0 +// CHECK-NEXT: 65536 +// CHECK-NEXT: 0 +// CHECK-NEXT: 131072 +// CHECK-NEXT: 0 +// CHECK-NEXT: 262144 +// CHECK-NEXT: 0 +// CHECK-NEXT: 524288 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1048576 +// CHECK-NEXT: 0 +// CHECK-NEXT: 2097152 +// CHECK-NEXT: 0 +// CHECK-NEXT: 4194304 +// CHECK-NEXT: 0 +// CHECK-NEXT: 8388608 +// CHECK-NEXT: 0 +// CHECK-NEXT: 16777216 +// CHECK-NEXT: 0 +// CHECK-NEXT: 33554432 +// CHECK-NEXT: 0 +// CHECK-NEXT: 67108864 +// CHECK-NEXT: 0 +// CHECK-NEXT: 134217728 +// CHECK-NEXT: 0 +// CHECK-NEXT: 268435456 +// CHECK-NEXT: 0 +// CHECK-NEXT: 536870912 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1073741824 +// CHECK-NEXT: 0 +// CHECK-NEXT: -2147483648 +// CHECK-NEXT: 0 +// CHECK-NEXT: 0 + +package main + +func testShrUint32(v uint32) { + for i := uint(0); i <= 32; i++ { + println(v >> i) + println(v << i) + } +} + +func testShrInt32(v int32) { + for i := uint(0); i <= 32; i++ { + println(v >> i) + println(v << i) + } +} + +func main() { + testShrUint32(0xFFFFFFFF) + testShrUint32(0xEFFFFFFF) + testShrInt32(-1) + testShrInt32(1) +} diff --git a/llgo/test/execution/slices/append.go b/llgo/test/execution/slices/append.go new file mode 100644 index 00000000000..50db2ac27f6 --- /dev/null +++ b/llgo/test/execution/slices/append.go @@ -0,0 +1,254 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 5 +// CHECK-NEXT: 6 +// CHECK-NEXT: 7 +// CHECK-NEXT: 8 +// CHECK-NEXT: 9 +// CHECK-NEXT: 10 +// CHECK-NEXT: 11 +// CHECK-NEXT: 12 +// CHECK-NEXT: 13 +// CHECK-NEXT: 14 +// CHECK-NEXT: 15 +// CHECK-NEXT: 16 +// CHECK-NEXT: 17 +// CHECK-NEXT: 18 +// CHECK-NEXT: 19 +// CHECK-NEXT: 20 +// CHECK-NEXT: 21 +// CHECK-NEXT: 22 +// CHECK-NEXT: 23 +// CHECK-NEXT: 24 +// CHECK-NEXT: 25 +// CHECK-NEXT: 26 +// CHECK-NEXT: 27 +// CHECK-NEXT: 28 +// CHECK-NEXT: 29 +// CHECK-NEXT: 30 +// CHECK-NEXT: 31 +// CHECK-NEXT: 32 +// CHECK-NEXT: 33 +// CHECK-NEXT: 34 +// CHECK-NEXT: 35 +// CHECK-NEXT: 36 +// CHECK-NEXT: 37 +// CHECK-NEXT: 38 +// CHECK-NEXT: 39 +// CHECK-NEXT: 40 +// CHECK-NEXT: 41 +// CHECK-NEXT: 42 +// CHECK-NEXT: 43 +// CHECK-NEXT: 44 +// CHECK-NEXT: 45 +// CHECK-NEXT: 46 +// CHECK-NEXT: 47 +// CHECK-NEXT: 48 +// CHECK-NEXT: 49 +// CHECK-NEXT: 50 +// CHECK-NEXT: 51 +// CHECK-NEXT: 52 +// CHECK-NEXT: 53 +// CHECK-NEXT: 54 +// CHECK-NEXT: 55 +// CHECK-NEXT: 56 +// CHECK-NEXT: 57 +// CHECK-NEXT: 58 +// CHECK-NEXT: 59 +// CHECK-NEXT: 60 +// CHECK-NEXT: 61 +// CHECK-NEXT: 62 +// CHECK-NEXT: 63 +// CHECK-NEXT: 64 +// CHECK-NEXT: 65 +// CHECK-NEXT: 66 +// CHECK-NEXT: 67 +// CHECK-NEXT: 68 +// CHECK-NEXT: 69 +// CHECK-NEXT: 70 +// CHECK-NEXT: 71 +// CHECK-NEXT: 72 +// CHECK-NEXT: 73 +// CHECK-NEXT: 74 +// CHECK-NEXT: 75 +// CHECK-NEXT: 76 +// CHECK-NEXT: 77 +// CHECK-NEXT: 78 +// CHECK-NEXT: 79 +// CHECK-NEXT: 80 +// CHECK-NEXT: 81 +// CHECK-NEXT: 82 +// CHECK-NEXT: 83 +// CHECK-NEXT: 84 +// CHECK-NEXT: 85 +// CHECK-NEXT: 86 +// CHECK-NEXT: 87 +// CHECK-NEXT: 88 +// CHECK-NEXT: 89 +// CHECK-NEXT: 90 +// CHECK-NEXT: 91 +// CHECK-NEXT: 92 +// CHECK-NEXT: 93 +// CHECK-NEXT: 94 +// CHECK-NEXT: 95 +// CHECK-NEXT: 96 +// CHECK-NEXT: 97 +// CHECK-NEXT: 98 +// CHECK-NEXT: 99 +// CHECK-NEXT: 0 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: 4 +// CHECK-NEXT: 5 +// CHECK-NEXT: 6 +// CHECK-NEXT: 7 +// CHECK-NEXT: 8 +// CHECK-NEXT: 9 +// CHECK-NEXT: 10 +// CHECK-NEXT: 11 +// CHECK-NEXT: 12 +// CHECK-NEXT: 13 +// CHECK-NEXT: 14 +// CHECK-NEXT: 15 +// CHECK-NEXT: 16 +// CHECK-NEXT: 17 +// CHECK-NEXT: 18 +// CHECK-NEXT: 19 +// CHECK-NEXT: 20 +// CHECK-NEXT: 21 +// CHECK-NEXT: 22 +// CHECK-NEXT: 23 +// CHECK-NEXT: 24 +// CHECK-NEXT: 25 +// CHECK-NEXT: 26 +// CHECK-NEXT: 27 +// CHECK-NEXT: 28 +// CHECK-NEXT: 29 +// CHECK-NEXT: 30 +// CHECK-NEXT: 31 +// CHECK-NEXT: 32 +// CHECK-NEXT: 33 +// CHECK-NEXT: 34 +// CHECK-NEXT: 35 +// CHECK-NEXT: 36 +// CHECK-NEXT: 37 +// CHECK-NEXT: 38 +// CHECK-NEXT: 39 +// CHECK-NEXT: 40 +// CHECK-NEXT: 41 +// CHECK-NEXT: 42 +// CHECK-NEXT: 43 +// CHECK-NEXT: 44 +// CHECK-NEXT: 45 +// CHECK-NEXT: 46 +// CHECK-NEXT: 47 +// CHECK-NEXT: 48 +// CHECK-NEXT: 49 +// CHECK-NEXT: 50 +// CHECK-NEXT: 51 +// CHECK-NEXT: 52 +// CHECK-NEXT: 53 +// CHECK-NEXT: 54 +// CHECK-NEXT: 55 +// CHECK-NEXT: 56 +// CHECK-NEXT: 57 +// CHECK-NEXT: 58 +// CHECK-NEXT: 59 +// CHECK-NEXT: 60 +// CHECK-NEXT: 61 +// CHECK-NEXT: 62 +// CHECK-NEXT: 63 +// CHECK-NEXT: 64 +// CHECK-NEXT: 65 +// CHECK-NEXT: 66 +// CHECK-NEXT: 67 +// CHECK-NEXT: 68 +// CHECK-NEXT: 69 +// CHECK-NEXT: 70 +// CHECK-NEXT: 71 +// CHECK-NEXT: 72 +// CHECK-NEXT: 73 +// CHECK-NEXT: 74 +// CHECK-NEXT: 75 +// CHECK-NEXT: 76 +// CHECK-NEXT: 77 +// CHECK-NEXT: 78 +// CHECK-NEXT: 79 +// CHECK-NEXT: 80 +// CHECK-NEXT: 81 +// CHECK-NEXT: 82 +// CHECK-NEXT: 83 +// CHECK-NEXT: 84 +// CHECK-NEXT: 85 +// CHECK-NEXT: 86 +// CHECK-NEXT: 87 +// CHECK-NEXT: 88 +// CHECK-NEXT: 89 +// CHECK-NEXT: 90 +// CHECK-NEXT: 91 +// CHECK-NEXT: 92 +// CHECK-NEXT: 93 +// CHECK-NEXT: 94 +// CHECK-NEXT: 95 +// CHECK-NEXT: 96 +// CHECK-NEXT: 97 +// CHECK-NEXT: 98 +// CHECK-NEXT: 99 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 +// CHECK-NEXT: abcdef +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: false false +// CHECK-NEXT: true true +// CHECK-NEXT: false false + +package main + +func stringtobytes() { + var b []byte + b = append(b, "abc"...) + b = append(b, "def"...) + println(string(b)) +} + +func appendnothing() { + var x []string + println(append(x) == nil) + x = append(x, "!") + println(len(append(x)) == 1) +} + +func appendmulti() { + a := append([]bool{}, []bool{false, true, false}...) + b := append([]bool{}, false, true, false) + for i := range a { + println(a[i], b[i]) + } +} + +func main() { + x := []int{} + for i := 0; i < 100; i++ { + x = append(x, i) + } + for i := 0; i < len(x); i++ { + println(x[i]) + } + y := []int{1, 2, 3} + x = append(x, y...) + for i := 0; i < len(x); i++ { + println(x[i]) + } + stringtobytes() + appendnothing() + appendmulti() +} diff --git a/llgo/test/execution/slices/cap.go b/llgo/test/execution/slices/cap.go new file mode 100644 index 00000000000..33a34ff1a38 --- /dev/null +++ b/llgo/test/execution/slices/cap.go @@ -0,0 +1,50 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 0 +// CHECK-NEXT: 0 0 +// CHECK-NEXT: 0 0 +// CHECK-NEXT: 1 1 +// CHECK-NEXT: 1 1 +// CHECK-NEXT: 1 2 +// CHECK-NEXT: 2 9 +// CHECK-NEXT: 3 9 +// CHECK-NEXT: 999 +// CHECK-NEXT: 999 +// CHECK-NEXT: 1 2 + +package main + +func test(l, c int) { + var s []int + if l != -1 { + if c == -1 { + s = make([]int, l) + } else { + s = make([]int, l, c) + } + } + println(len(s), cap(s)) +} + +func main() { + test(-1, -1) + test(0, -1) + test(0, 0) + test(1, -1) + test(1, 1) + test(1, 2) + + // make sure capacity is transferred to slice + s := make([]int, 5, 10) + s1 := s[1:3] + println(len(s1), cap(s1)) + + s2 := append(s1, 999) + println(len(s2), cap(s2)) + println(s2[2]) + println(s[3]) + + s3 := s1[0:1:2] + println(len(s3), cap(s3)) +} diff --git a/llgo/test/execution/slices/compare.go b/llgo/test/execution/slices/compare.go new file mode 100644 index 00000000000..93e3071397e --- /dev/null +++ b/llgo/test/execution/slices/compare.go @@ -0,0 +1,26 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: true + +package main + +func main() { + var s []int + println(s == nil) + println(s != nil) + println(nil == s) + println(nil != s) + s = make([]int, 0) + println(s == nil) + println(s != nil) + println(nil == s) + println(nil != s) +} diff --git a/llgo/test/execution/slices/copy.go b/llgo/test/execution/slices/copy.go new file mode 100644 index 00000000000..a6bf6c56454 --- /dev/null +++ b/llgo/test/execution/slices/copy.go @@ -0,0 +1,17 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 5 +// CHECK-NEXT: 0 + +package main + +func main() { + a := make([]int, 10) + b := make([]int, 10) + for i, _ := range b { + b[i] = 1 + } + println(copy(a[:5], b)) // expect 5 + println(a[5]) // expect 0 +} diff --git a/llgo/test/execution/slices/index.go b/llgo/test/execution/slices/index.go new file mode 100644 index 00000000000..20d213e1a4e --- /dev/null +++ b/llgo/test/execution/slices/index.go @@ -0,0 +1,14 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 + +package main + +func blah() []int { + return make([]int, 1) +} + +func main() { + println(blah()[0]) +} diff --git a/llgo/test/execution/slices/literal.go b/llgo/test/execution/slices/literal.go new file mode 100644 index 00000000000..42adabf76bd --- /dev/null +++ b/llgo/test/execution/slices/literal.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 + +package main + +func main() { + x := []int{1, 2, 3} + for i := 0; i < len(x); i++ { + println(x[i]) + } +} diff --git a/llgo/test/execution/slices/make.go b/llgo/test/execution/slices/make.go new file mode 100644 index 00000000000..30ecd6cbb0e --- /dev/null +++ b/llgo/test/execution/slices/make.go @@ -0,0 +1,23 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 0 +// CHECK-NEXT: 1 0 +// CHECK-NEXT: 2 0 +// CHECK-NEXT: 3 0 +// CHECK-NEXT: 4 0 +// CHECK-NEXT: 5 666 +// CHECK-NEXT: 6 0 +// CHECK-NEXT: 7 0 +// CHECK-NEXT: 8 0 +// CHECK-NEXT: 9 0 + +package main + +func main() { + x := make([]int, 10) + x[5] = 666 + for i, val := range x { + println(i, val) + } +} diff --git a/llgo/test/execution/slices/sliceexpr.go b/llgo/test/execution/slices/sliceexpr.go new file mode 100644 index 00000000000..56a7b528d9f --- /dev/null +++ b/llgo/test/execution/slices/sliceexpr.go @@ -0,0 +1,39 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: a +// CHECK-NEXT: 0 2 +// CHECK-NEXT: 1 3 +// CHECK-NEXT: b +// CHECK-NEXT: 0 3 +// CHECK-NEXT: 1 4 +// CHECK-NEXT: c +// CHECK-NEXT: 0 1 +// CHECK-NEXT: 1 2 +// CHECK-NEXT: d +// CHECK-NEXT: 0 1 +// CHECK-NEXT: 1 2 +// CHECK-NEXT: 2 3 +// CHECK-NEXT: 3 4 + +package main + +func main() { + x := []int{1, 2, 3, 4} + println("a") + for i, val := range x[1:3] { + println(i, val) + } + println("b") + for i, val := range x[2:] { + println(i, val) + } + println("c") + for i, val := range x[:2] { + println(i, val) + } + println("d") + for i, val := range x[:] { + println(i, val) + } +} diff --git a/llgo/test/execution/strings/add.go b/llgo/test/execution/strings/add.go new file mode 100644 index 00000000000..daf69215591 --- /dev/null +++ b/llgo/test/execution/strings/add.go @@ -0,0 +1,15 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 3 3 6 +// CHECK-NEXT: abc123 + +package main + +func main() { + a := "abc" + b := "123" + c := a + b + println(len(a), len(b), len(c)) + println(c) +} diff --git a/llgo/test/execution/strings/bytes.go b/llgo/test/execution/strings/bytes.go new file mode 100644 index 00000000000..a2c450a1747 --- /dev/null +++ b/llgo/test/execution/strings/bytes.go @@ -0,0 +1,41 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: testBytesConversion: true +// CHECK-NEXT: 97 +// CHECK-NEXT: 98 +// CHECK-NEXT: 99 +// CHECK-NEXT: abc +// CHECK-NEXT: !bc +// CHECK-NEXT: testBytesCopy: true + +package main + +type namedByte byte + +func testBytesConversion() { + s := "abc" + b := []byte(s) + println("testBytesConversion:", s == string(b)) + nb := []namedByte(s) + for _, v := range nb { + println(v) + } + b[0] = '!' + println(s) + s = string(b) + b[0] = 'a' + println(s) +} + +func testBytesCopy() { + s := "abc" + b := make([]byte, len(s)) + copy(b, s) + println("testBytesCopy:", string(b) == s) +} + +func main() { + testBytesConversion() + testBytesCopy() +} diff --git a/llgo/test/execution/strings/compare.go b/llgo/test/execution/strings/compare.go new file mode 100644 index 00000000000..c8e4f0914d2 --- /dev/null +++ b/llgo/test/execution/strings/compare.go @@ -0,0 +1,54 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true + +package main + +func main() { + x := "abc" + y := "def" + z := "abcd" + + println(x == x) // true + println(x == y) // false + println(x != x) // false + println(x != y) // true + println(x < x) // false + println(x < y) // true + println(y < x) // false + println(x > x) // false + println(x > y) // false + println(y > x) // true + + println(x == z) // false + println(z == x) // false + println(x < z) // true + println(x > z) // false + println(z < x) // false + println(z > x) // true + + println(x <= x) // true + println(x <= y) // true + println(x >= x) // true + println(y >= x) // true +} diff --git a/llgo/test/execution/strings/index.go b/llgo/test/execution/strings/index.go new file mode 100644 index 00000000000..dca7ddf8f10 --- /dev/null +++ b/llgo/test/execution/strings/index.go @@ -0,0 +1,11 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 97 98 99 + +package main + +func main() { + s := "abc" + println(s[0], s[1], s[2]) +} diff --git a/llgo/test/execution/strings/range.go b/llgo/test/execution/strings/range.go new file mode 100644 index 00000000000..c68b02a6680 --- /dev/null +++ b/llgo/test/execution/strings/range.go @@ -0,0 +1,86 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 46 1 +// CHECK-NEXT: 0 46 +// CHECK-NEXT: 0 169 1 +// CHECK-NEXT: 0 169 +// CHECK-NEXT: 0 8364 1 +// CHECK-NEXT: 0 8364 +// CHECK-NEXT: 0 66560 1 +// CHECK-NEXT: 0 66560 +// CHECK-NEXT: 0 83 1 +// CHECK-NEXT: 1 97 2 +// CHECK-NEXT: 2 108 3 +// CHECK-NEXT: 3 101 4 +// CHECK-NEXT: 4 32 5 +// CHECK-NEXT: 5 112 6 +// CHECK-NEXT: 6 114 7 +// CHECK-NEXT: 7 105 8 +// CHECK-NEXT: 8 99 9 +// CHECK-NEXT: 9 101 10 +// CHECK-NEXT: 10 58 11 +// CHECK-NEXT: 11 32 12 +// CHECK-NEXT: 12 8364 13 +// CHECK-NEXT: 15 48 14 +// CHECK-NEXT: 16 46 15 +// CHECK-NEXT: 17 57 16 +// CHECK-NEXT: 18 57 17 +// CHECK-NEXT: 0 83 +// CHECK-NEXT: 1 97 +// CHECK-NEXT: 2 108 +// CHECK-NEXT: 3 101 +// CHECK-NEXT: 4 32 +// CHECK-NEXT: 5 112 +// CHECK-NEXT: 6 114 +// CHECK-NEXT: 7 105 +// CHECK-NEXT: 8 99 +// CHECK-NEXT: 9 101 +// CHECK-NEXT: 10 58 +// CHECK-NEXT: 11 32 +// CHECK-NEXT: 12 8364 +// CHECK-NEXT: 15 48 +// CHECK-NEXT: 16 46 +// CHECK-NEXT: 17 57 +// CHECK-NEXT: 18 57 + +package main + +func printchars(s string) { + var x int + for i, c := range s { + // test loop-carried dependence (x++), introducing a Phi node + x++ + println(i, c, x) + } + + // now test with plain old assignment + var i int + var c rune + for i, c = range s { + println(i, c) + if i == len(s)-1 { + // test multiple branches to loop header + continue + } + } +} + +func main() { + // 1 bytes + printchars(".") + + // 2 bytes + printchars("©") + + // 3 bytes + printchars("€") + + // 4 bytes + printchars("𐐀") + + // mixed + printchars("Sale price: €0.99") + + // TODO add test cases for invalid sequences +} diff --git a/llgo/test/execution/strings/runetostring.go b/llgo/test/execution/strings/runetostring.go new file mode 100644 index 00000000000..e6a8c5de413 --- /dev/null +++ b/llgo/test/execution/strings/runetostring.go @@ -0,0 +1,74 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: test( 46 ) +// CHECK-NEXT: . +// CHECK-NEXT: 46 +// CHECK-NEXT: 0 46 +// CHECK-NEXT: test( 169 ) +// CHECK-NEXT: © +// CHECK-NEXT: 194 +// CHECK-NEXT: 169 +// CHECK-NEXT: 0 169 +// CHECK-NEXT: test( 8364 ) +// CHECK-NEXT: € +// CHECK-NEXT: 226 +// CHECK-NEXT: 130 +// CHECK-NEXT: 172 +// CHECK-NEXT: 0 8364 +// CHECK-NEXT: test( 66560 ) +// CHECK-NEXT: 𐐀 +// CHECK-NEXT: 240 +// CHECK-NEXT: 144 +// CHECK-NEXT: 144 +// CHECK-NEXT: 128 +// CHECK-NEXT: 0 66560 +// CHECK-NEXT: .©€𐐀 +// CHECK-NEXT: 4 4 4 +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: true + +package main + +func test(r rune) { + println("test(", r, ")") + s := string(r) + println(s) + for i := 0; i < len(s); i++ { + println(s[i]) + } + for i, r := range s { + println(i, r) + } +} + +type namedRune rune + +func testslice(r1 []rune) { + s := string(r1) + println(s) + r2 := []rune(s) + r3 := []namedRune(s) + println(len(r1), len(r2), len(r3)) + if len(r2) == len(r1) && len(r3) == len(r1) { + for i := range r2 { + println(r1[i] == r2[i]) + println(r1[i] == rune(r3[i])) + } + } +} + +func main() { + var runes = []rune{'.', '©', '€', '𐐀'} + test(runes[0]) + test(runes[1]) + test(runes[2]) + test(runes[3]) + testslice(runes) +} diff --git a/llgo/test/execution/strings/slice.go b/llgo/test/execution/strings/slice.go new file mode 100644 index 00000000000..ec1b40ce719 --- /dev/null +++ b/llgo/test/execution/strings/slice.go @@ -0,0 +1,17 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: abcdef +// CHECK-NEXT: bcdef +// CHECK-NEXT: abc +// CHECK-NEXT: bcd + +package main + +func main() { + s := "abcdef" + println(s[:]) + println(s[1:]) + println(s[:3]) + println(s[1:4]) +} diff --git a/llgo/test/execution/structs/compare.go b/llgo/test/execution/structs/compare.go new file mode 100644 index 00000000000..20a8ead72f7 --- /dev/null +++ b/llgo/test/execution/structs/compare.go @@ -0,0 +1,52 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true +// CHECK-NEXT: true +// CHECK-NEXT: false +// CHECK-NEXT: false +// CHECK-NEXT: true + +package main + +type S0 struct{} + +type S1 struct { + a int +} + +type S2 struct { + a, b int +} + +func testS0() { + println(S0{} == S0{}) + println(S0{} != S0{}) +} + +func testS1() { + println(S1{1} == S1{1}) + println(S1{1} != S1{1}) + println(S1{1} == S1{2}) + println(S1{1} != S1{2}) +} + +func testS2() { + s1 := S2{1, 2} + s2 := S2{1, 3} + println(s1 == s1) + println(s1 == s2) + println(s1 != s1) + println(s1 != s2) +} + +func main() { + testS0() + testS1() + testS2() +} diff --git a/llgo/test/execution/structs/embed.go b/llgo/test/execution/structs/embed.go new file mode 100644 index 00000000000..d5197945eef --- /dev/null +++ b/llgo/test/execution/structs/embed.go @@ -0,0 +1,58 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: A.test 1 +// CHECK-NEXT: A.testA +// CHECK-NEXT: A.testA2 +// CHECK-NEXT: B.test 2 +// CHECK-NEXT: A.testA +// CHECK-NEXT: A.testA2 +// CHECK-NEXT: A.testA + +package main + +type A struct{ aval int } + +func (a *A) test() { + println("A.test", a.aval) +} + +func (a *A) testA() { + println("A.testA") +} + +func (a A) testA2() { + println("A.testA2") +} + +type B struct { + A + bval int +} + +func (b B) test() { + println("B.test", b.bval) +} + +type C struct { + *B + cval int +} + +func main() { + var b B + b.aval = 1 + b.bval = 2 + b.A.test() + b.A.testA() + b.A.testA2() + b.test() + b.testA() + b.testA2() + + var c C + c.B = &b + c.cval = 3 + c.testA() + //c.testA2() +} diff --git a/llgo/test/execution/switch/branch.go b/llgo/test/execution/switch/branch.go new file mode 100644 index 00000000000..a7bca9a7bed --- /dev/null +++ b/llgo/test/execution/switch/branch.go @@ -0,0 +1,23 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: true +// CHECK-NEXT: false + +package main + +func main() { + switch true { + default: + break + println("default") + } + + switch true { + case true: + println("true") + fallthrough + case false: + println("false") + } +} diff --git a/llgo/test/execution/switch/default.go b/llgo/test/execution/switch/default.go new file mode 100644 index 00000000000..2ae85097070 --- /dev/null +++ b/llgo/test/execution/switch/default.go @@ -0,0 +1,21 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: default +// CHECK-NEXT: true + +package main + +func main() { + switch true { + default: + println("default") + } + + switch { + default: + println("default") + case true: + println("true") + } +} diff --git a/llgo/test/execution/switch/empty.go b/llgo/test/execution/switch/empty.go new file mode 100644 index 00000000000..4d20679e4b1 --- /dev/null +++ b/llgo/test/execution/switch/empty.go @@ -0,0 +1,16 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: f was called + +package main + +func f() int { + println("f was called") + return 123 +} + +func main() { + switch f() { + } +} diff --git a/llgo/test/execution/switch/scope.go b/llgo/test/execution/switch/scope.go new file mode 100644 index 00000000000..73bab3cd747 --- /dev/null +++ b/llgo/test/execution/switch/scope.go @@ -0,0 +1,20 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 +// CHECK-NEXT: 2 + +package main + +func main() { + // case clauses have their own scope. + switch { + case true, false: + x := 1 + println(x) + fallthrough + default: + x := 2 + println(x) + } +} diff --git a/llgo/test/execution/switch/strings.go b/llgo/test/execution/switch/strings.go new file mode 100644 index 00000000000..7f0c99d441c --- /dev/null +++ b/llgo/test/execution/switch/strings.go @@ -0,0 +1,21 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: abc +// CHECK-NEXT: def, abc + +package main + +func main() { + switch "abc" { + case "def": + println("def") + case "abc": + println("abc") + } + + switch "abc" { + case "def", "abc": + println("def, abc") + } +} diff --git a/llgo/test/execution/switch/type.go b/llgo/test/execution/switch/type.go new file mode 100644 index 00000000000..b43231cd935 --- /dev/null +++ b/llgo/test/execution/switch/type.go @@ -0,0 +1,72 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: int64 123 +// CHECK-NEXT: default +// CHECK-NEXT: uint8 or int8 +// CHECK-NEXT: uint8 or int8 +// CHECK-NEXT: N + +package main + +func test(i interface{}) { + switch x := i.(type) { + case int64: + println("int64", x) + // FIXME + //case string: + // println("string", x) + default: + println("default") + } +} + +type stringer interface { + String() string +} + +func printany(i interface{}) { + switch v := i.(type) { + case nil: + print("nil", v) + case stringer: + print(v.String()) + case error: + print(v.Error()) + case int: + print(v) + case string: + print(v) + } +} + +func multi(i interface{}) { + switch i.(type) { + case uint8, int8: + println("uint8 or int8") + default: + println("something else") + } +} + +type N int + +func (n N) String() string { return "N" } + +func named() { + var x interface{} = N(123) + switch x := x.(type) { + case N: + // Test for bug: previously, type switch was + // assigning underlying type of N (int). + println(x.String()) + } +} + +func main() { + test(int64(123)) + test("abc") + multi(uint8(123)) + multi(int8(123)) + named() +} diff --git a/llgo/test/execution/types/named.go b/llgo/test/execution/types/named.go new file mode 100644 index 00000000000..08fd791ec83 --- /dev/null +++ b/llgo/test/execution/types/named.go @@ -0,0 +1,37 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 24 +// CHECK-NEXT: 16 +// CHECK-NEXT: 0 + +package main + +import "unsafe" + +func f1() { + type T struct { + a, b, c int + } + var t T + println(unsafe.Sizeof(t)) +} + +func f2() { + type T interface{} + var t T + t = 1 + println(unsafe.Sizeof(t)) +} + +func f3() { + type T struct{} + var t T + println(unsafe.Sizeof(t)) +} + +func main() { + f1() + f2() + f3() +} diff --git a/llgo/test/execution/types/recursive.go b/llgo/test/execution/types/recursive.go new file mode 100644 index 00000000000..69ac09b45fb --- /dev/null +++ b/llgo/test/execution/types/recursive.go @@ -0,0 +1,29 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 3 +// CHECK-NEXT: 4 + +package main + +type T1 *T1 + +func count(t T1) int { + if t == nil { + return 1 + } + return 1 + count(*t) +} + +func testSelfPointer() { + var a T1 + var b T1 + var c T1 = &b + *c = &a + println(count(c)) + println(count(&c)) +} + +func main() { + testSelfPointer() +} diff --git a/llgo/test/execution/unsafe/const_sizeof.go b/llgo/test/execution/unsafe/const_sizeof.go new file mode 100644 index 00000000000..ade9d0bc22b --- /dev/null +++ b/llgo/test/execution/unsafe/const_sizeof.go @@ -0,0 +1,18 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 8 +// CHECK-NEXT: 8 + +package main + +import "unsafe" + +const ptrSize = unsafe.Sizeof((*byte)(nil)) + +var x [ptrSize]int + +func main() { + println(ptrSize) + println(len(x)) +} diff --git a/llgo/test/execution/unsafe/offsetof.go b/llgo/test/execution/unsafe/offsetof.go new file mode 100644 index 00000000000..88b313ab5e1 --- /dev/null +++ b/llgo/test/execution/unsafe/offsetof.go @@ -0,0 +1,26 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 0 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 16 + +package main + +import "unsafe" + +type S struct { + a int16 + b int32 + c int8 + d int64 +} + +func main() { + var s S + println(unsafe.Offsetof(s.a)) + println(unsafe.Offsetof(s.b)) + println(unsafe.Offsetof(s.c)) + println(unsafe.Offsetof(s.d)) +} diff --git a/llgo/test/execution/unsafe/pointer.go b/llgo/test/execution/unsafe/pointer.go new file mode 100644 index 00000000000..20dc64f073f --- /dev/null +++ b/llgo/test/execution/unsafe/pointer.go @@ -0,0 +1,21 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 123 +// CHECK-NEXT: 456 + +package main + +import "unsafe" + +func main() { + var i [2]int + i[0] = 123 + i[1] = 456 + ptr := &i[0] + println(*ptr) + ptr_i := unsafe.Pointer(ptr) + ptr_i = unsafe.Pointer(uintptr(ptr_i) + unsafe.Sizeof(i[0])) + ptr = (*int)(ptr_i) + println(*ptr) +} diff --git a/llgo/test/execution/unsafe/sizeof_array.go b/llgo/test/execution/unsafe/sizeof_array.go new file mode 100644 index 00000000000..2928de79327 --- /dev/null +++ b/llgo/test/execution/unsafe/sizeof_array.go @@ -0,0 +1,18 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 12 + +package main + +import "unsafe" + +type uint24 struct { + a uint16 + b uint8 +} + +func main() { + var a [3]uint24 + println(unsafe.Sizeof(a)) +} diff --git a/llgo/test/execution/unsafe/sizeof_basic.go b/llgo/test/execution/unsafe/sizeof_basic.go new file mode 100644 index 00000000000..a9a467bd114 --- /dev/null +++ b/llgo/test/execution/unsafe/sizeof_basic.go @@ -0,0 +1,102 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 1 +// CHECK-NEXT: 8 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 16 +// CHECK-NEXT: 16 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 1 +// CHECK-NEXT: 8 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 4 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 +// CHECK-NEXT: 8 + +package main + +import "unsafe" + +func main() { + var b bool + var i int + var i8 int8 + var i16 int16 + var i32 int32 + var i64 int64 + var u uint + var u8 uint8 + var u16 uint16 + var u32 uint32 + var u64 uint64 + var f32 float32 + var f64 float64 + var c64 complex64 + var c128 complex128 + var s string + var p unsafe.Pointer + var up uintptr + + println(unsafe.Sizeof(b)) + println(unsafe.Sizeof(i)) + println(unsafe.Sizeof(i8)) + println(unsafe.Sizeof(i16)) + println(unsafe.Sizeof(i32)) + println(unsafe.Sizeof(i64)) + println(unsafe.Sizeof(u)) + println(unsafe.Sizeof(u8)) + println(unsafe.Sizeof(u16)) + println(unsafe.Sizeof(u32)) + println(unsafe.Sizeof(u64)) + println(unsafe.Sizeof(f32)) + println(unsafe.Sizeof(f64)) + println(unsafe.Sizeof(c64)) + println(unsafe.Sizeof(c128)) + println(unsafe.Sizeof(s)) + println(unsafe.Sizeof(p)) + println(unsafe.Sizeof(up)) + + println(unsafe.Alignof(b)) + println(unsafe.Alignof(i)) + println(unsafe.Alignof(i8)) + println(unsafe.Alignof(i16)) + println(unsafe.Alignof(i32)) + println(unsafe.Alignof(i64)) + println(unsafe.Alignof(u)) + println(unsafe.Alignof(u8)) + println(unsafe.Alignof(u16)) + println(unsafe.Alignof(u32)) + println(unsafe.Alignof(u64)) + println(unsafe.Alignof(f32)) + println(unsafe.Alignof(f64)) + println(unsafe.Alignof(c64)) + println(unsafe.Alignof(c128)) + println(unsafe.Alignof(s)) + println(unsafe.Alignof(p)) + println(unsafe.Alignof(up)) +} diff --git a/llgo/test/execution/unsafe/sizeof_struct.go b/llgo/test/execution/unsafe/sizeof_struct.go new file mode 100644 index 00000000000..e8612d2ea6c --- /dev/null +++ b/llgo/test/execution/unsafe/sizeof_struct.go @@ -0,0 +1,19 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 24 + +package main + +import "unsafe" + +type a struct { + a int16 + b int32 + c int8 + d int64 +} + +func main() { + println(unsafe.Sizeof(a{})) +} diff --git a/llgo/test/execution/var.go b/llgo/test/execution/var.go new file mode 100644 index 00000000000..71b025df45b --- /dev/null +++ b/llgo/test/execution/var.go @@ -0,0 +1,37 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: woobie +// CHECK-NEXT: 579 456 +// CHECK-NEXT: 12 +3.450000e+000 +// CHECK-NEXT: -1 + +package main + +func Blah() int { + println("woobie") + return 123 +} + +func F1() (int, float64) { + return 12, 3.45 +} + +var X = Y + Blah() // == 579 +var Y = 123 + Z // == 456 + +var X1, Y1 = F1() + +const ( + _ = 333 * iota + Z +) + +var I interface{} = -1 +var I1 = I.(int) + +func main() { + println(X, Y) + println(X1, Y1) + println(I1) +} diff --git a/llgo/test/execution/varargs.go b/llgo/test/execution/varargs.go new file mode 100644 index 00000000000..ca994164e46 --- /dev/null +++ b/llgo/test/execution/varargs.go @@ -0,0 +1,31 @@ +// RUN: llgo -o %t %s +// RUN: %t 2>&1 | FileCheck %s + +// CHECK: 3 +// CHECK-NEXT: 123 +// CHECK-NEXT: 456 +// CHECK-NEXT: 789 +// CHECK-NEXT: 4 +// CHECK-NEXT: 123 +// CHECK-NEXT: 456 +// CHECK-NEXT: 789 +// CHECK-NEXT: 101112 +// CHECK-NEXT: 3 +// CHECK-NEXT: 1 +// CHECK-NEXT: 2 +// CHECK-NEXT: 3 + +package main + +func p(i ...int) { + println(len(i)) + for j := 0; j < len(i); j++ { + println(i[j]) + } +} + +func main() { + p(123, 456, 789) + p(123, 456, 789, 101112) + p([]int{1, 2, 3}...) +} diff --git a/llgo/test/gllgo/dead.go b/llgo/test/gllgo/dead.go new file mode 100644 index 00000000000..31d0de85487 --- /dev/null +++ b/llgo/test/gllgo/dead.go @@ -0,0 +1,6 @@ +// RUN: llgo -O0 -S -o - %s | FileCheck %s + +package gotest + +// CHECK-NOT: deadfunc +func deadfunc() diff --git a/llgo/test/irgen/cabi.go b/llgo/test/irgen/cabi.go new file mode 100644 index 00000000000..efa448949c8 --- /dev/null +++ b/llgo/test/irgen/cabi.go @@ -0,0 +1,23 @@ +// RUN: llgo -S -emit-llvm -o - %s | FileCheck %s + +package foo + +// CHECK: define void @foo.Test01_SI8(i8 signext) +func Test01_SI8(x int8) {} +// CHECK: define void @foo.Test02_UI8(i8 zeroext) +func Test02_UI8(x uint8) {} + +// CHECK: define void @foo.Test03_SI16(i16 signext) +func Test03_SI16(x int16) {} +// CHECK: define void @foo.Test04_UI16(i16 zeroext) +func Test04_UI16(x uint16) {} + +// CHECK: define void @foo.Test05_SI32(i32) +func Test05_SI32(x int32) {} +// CHECK: define void @foo.Test06_UI32(i32) +func Test06_UI32(x uint32) {} + +// CHECK: define void @foo.Test07_SI64(i64) +func Test07_SI64(x int64) {} +// CHECK: define void @foo.Test08_UI64(i64) +func Test08_UI64(x uint64) {} diff --git a/llgo/test/irgen/mangling.go b/llgo/test/irgen/mangling.go new file mode 100644 index 00000000000..aff73cb8acb --- /dev/null +++ b/llgo/test/irgen/mangling.go @@ -0,0 +1,7 @@ +// RUN: llgo -fgo-pkgpath=llvm.org/llvm -S -emit-llvm -o - %s | FileCheck %s + +package llvm + +// CHECK: @llvm_org_llvm.F +func F() { +} diff --git a/llgo/test/lit.cfg b/llgo/test/lit.cfg new file mode 100644 index 00000000000..e4639abdf10 --- /dev/null +++ b/llgo/test/lit.cfg @@ -0,0 +1,15 @@ +import lit.formats +import os +import sys + +config.name = 'llgo' +config.suffixes = ['.go'] +config.test_format = lit.formats.ShTest() +config.test_source_root = config.llvm_src_root + '/tools/llgo/test' +config.test_exec_root = config.llvm_obj_root + '/tools/llgo/test' +config.excludes = ['Inputs'] + +config.substitutions.append((r"\bllgo\b", config.llvm_obj_root + '/bin/llgo -static-libgo')) +config.substitutions.append((r"\bFileCheck\b", config.llvm_obj_root + '/bin/FileCheck')) +config.substitutions.append((r"\bcount\b", config.llvm_obj_root + '/bin/count')) +config.substitutions.append((r"\bnot\b", config.llvm_obj_root + '/bin/not')) diff --git a/llgo/test/lit.site.cfg.in b/llgo/test/lit.site.cfg.in new file mode 100644 index 00000000000..2c3838618bf --- /dev/null +++ b/llgo/test/lit.site.cfg.in @@ -0,0 +1,4 @@ +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" + +lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg") |

