golang.org/x/tools@v0.21.0/internal/refactor/inline/falcon_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package inline_test 6 7 import "testing" 8 9 // Testcases mostly come in pairs, of a success and a failure 10 // to substitute based on specific constant argument values. 11 12 func TestFalconStringIndex(t *testing.T) { 13 runTests(t, []testcase{ 14 { 15 "Non-negative string index.", 16 `func f(i int) byte { return s[i] }; var s string`, 17 `func _() { f(0) }`, 18 `func _() { _ = s[0] }`, 19 }, 20 { 21 "Negative string index.", 22 `func f(i int) byte { return s[i] }; var s string`, 23 `func _() { f(-1) }`, 24 `func _() { 25 var i int = -1 26 _ = s[i] 27 }`, 28 }, 29 { 30 "String index in range.", 31 `func f(s string, i int) byte { return s[i] }`, 32 `func _() { f("-", 0) }`, 33 `func _() { _ = "-"[0] }`, 34 }, 35 { 36 "String index out of range.", 37 `func f(s string, i int) byte { return s[i] }`, 38 `func _() { f("-", 1) }`, 39 `func _() { 40 var ( 41 s string = "-" 42 i int = 1 43 ) 44 _ = s[i] 45 }`, 46 }, 47 { 48 "Remove known prefix (OK)", 49 `func f(s, prefix string) string { return s[:len(prefix)] }`, 50 `func _() { f("", "") }`, 51 `func _() { _ = ""[:len("")] }`, 52 }, 53 { 54 "Remove not-a-prefix (out of range)", 55 `func f(s, prefix string) string { return s[:len(prefix)] }`, 56 `func _() { f("", "pre") }`, 57 `func _() { 58 var s, prefix string = "", "pre" 59 _ = s[:len(prefix)] 60 }`, 61 }, 62 }) 63 } 64 65 func TestFalconSliceIndices(t *testing.T) { 66 runTests(t, []testcase{ 67 { 68 "Monotonic (0<=i<=j) slice indices (len unknown).", 69 `func f(i, j int) []int { return s[i:j] }; var s []int`, 70 `func _() { f(0, 1) }`, 71 `func _() { _ = s[0:1] }`, 72 }, 73 { 74 "Non-monotonic slice indices (len unknown).", 75 `func f(i, j int) []int { return s[i:j] }; var s []int`, 76 `func _() { f(1, 0) }`, 77 `func _() { 78 var i, j int = 1, 0 79 _ = s[i:j] 80 }`, 81 }, 82 { 83 "Negative slice index.", 84 `func f(i, j int) []int { return s[i:j] }; var s []int`, 85 `func _() { f(-1, 1) }`, 86 `func _() { 87 var i, j int = -1, 1 88 _ = s[i:j] 89 }`, 90 }, 91 }) 92 } 93 94 func TestFalconMapKeys(t *testing.T) { 95 runTests(t, []testcase{ 96 { 97 "Unique map keys (int)", 98 `func f(x int) { _ = map[int]bool{1: true, x: true} }`, 99 `func _() { f(2) }`, 100 `func _() { _ = map[int]bool{1: true, 2: true} }`, 101 }, 102 { 103 "Duplicate map keys (int)", 104 `func f(x int) { _ = map[int]bool{1: true, x: true} }`, 105 `func _() { f(1) }`, 106 `func _() { 107 var x int = 1 108 _ = map[int]bool{1: true, x: true} 109 }`, 110 }, 111 { 112 "Unique map keys (varied built-in types)", 113 `func f(x int16) { _ = map[any]bool{1: true, x: true} }`, 114 `func _() { f(2) }`, 115 `func _() { _ = map[any]bool{1: true, int16(2): true} }`, 116 }, 117 { 118 "Duplicate map keys (varied built-in types)", 119 `func f(x int16) { _ = map[any]bool{1: true, x: true} }`, 120 `func _() { f(1) }`, 121 `func _() { _ = map[any]bool{1: true, int16(1): true} }`, 122 }, 123 { 124 "Unique map keys (varied user-defined types)", 125 `func f(x myint) { _ = map[any]bool{1: true, x: true} }; type myint int`, 126 `func _() { f(2) }`, 127 `func _() { _ = map[any]bool{1: true, myint(2): true} }`, 128 }, 129 { 130 "Duplicate map keys (varied user-defined types)", 131 `func f(x myint, y myint2) { _ = map[any]bool{x: true, y: true} }; type (myint int; myint2 int)`, 132 `func _() { f(1, 1) }`, 133 `func _() { 134 var ( 135 x myint = 1 136 y myint2 = 1 137 ) 138 _ = map[any]bool{x: true, y: true} 139 }`, 140 }, 141 { 142 "Duplicate map keys (user-defined alias to built-in)", 143 `func f(x myint, y int) { _ = map[any]bool{x: true, y: true} }; type myint = int`, 144 `func _() { f(1, 1) }`, 145 `func _() { 146 var ( 147 x myint = 1 148 y int = 1 149 ) 150 _ = map[any]bool{x: true, y: true} 151 }`, 152 }, 153 }) 154 } 155 156 func TestFalconSwitchCases(t *testing.T) { 157 runTests(t, []testcase{ 158 { 159 "Unique switch cases (int).", 160 `func f(x int) { switch 0 { case x: case 1: } }`, 161 `func _() { f(2) }`, 162 `func _() { 163 switch 0 { 164 case 2: 165 case 1: 166 } 167 }`, 168 }, 169 { 170 "Duplicate switch cases (int).", 171 `func f(x int) { switch 0 { case x: case 1: } }`, 172 `func _() { f(1) }`, 173 `func _() { 174 var x int = 1 175 switch 0 { 176 case x: 177 case 1: 178 } 179 }`, 180 }, 181 { 182 "Unique switch cases (varied built-in types).", 183 `func f(x int) { switch any(nil) { case x: case int16(1): } }`, 184 `func _() { f(2) }`, 185 `func _() { 186 switch any(nil) { 187 case 2: 188 case int16(1): 189 } 190 }`, 191 }, 192 { 193 "Duplicate switch cases (varied built-in types).", 194 `func f(x int) { switch any(nil) { case x: case int16(1): } }`, 195 `func _() { f(1) }`, 196 `func _() { 197 switch any(nil) { 198 case 1: 199 case int16(1): 200 } 201 }`, 202 }, 203 }) 204 } 205 206 func TestFalconDivision(t *testing.T) { 207 runTests(t, []testcase{ 208 { 209 "Division by two.", 210 `func f(x, y int) int { return x / y }`, 211 `func _() { f(1, 2) }`, 212 `func _() { _ = 1 / 2 }`, 213 }, 214 { 215 "Division by zero.", 216 `func f(x, y int) int { return x / y }`, 217 `func _() { f(1, 0) }`, 218 `func _() { 219 var x, y int = 1, 0 220 _ = x / y 221 }`, 222 }, 223 { 224 "Division by two (statement).", 225 `func f(x, y int) { x /= y }`, 226 `func _() { f(1, 2) }`, 227 `func _() { 228 var x int = 1 229 x /= 2 230 }`, 231 }, 232 { 233 "Division by zero (statement).", 234 `func f(x, y int) { x /= y }`, 235 `func _() { f(1, 0) }`, 236 `func _() { 237 var x, y int = 1, 0 238 x /= y 239 }`, 240 }, 241 { 242 "Division of minint by two (ok).", 243 `func f(x, y int32) { _ = x / y }`, 244 `func _() { f(-0x80000000, 2) }`, 245 `func _() { _ = int32(-0x80000000) / int32(2) }`, 246 }, 247 { 248 "Division of minint by -1 (overflow).", 249 `func f(x, y int32) { _ = x / y }`, 250 `func _() { f(-0x80000000, -1) }`, 251 `func _() { 252 var x, y int32 = -0x80000000, -1 253 _ = x / y 254 }`, 255 }, 256 }) 257 } 258 259 func TestFalconMinusMinInt(t *testing.T) { 260 runTests(t, []testcase{ 261 { 262 "Negation of maxint.", 263 `func f(x int32) int32 { return -x }`, 264 `func _() { f(0x7fffffff) }`, 265 `func _() { _ = -int32(0x7fffffff) }`, 266 }, 267 { 268 "Negation of minint.", 269 `func f(x int32) int32 { return -x }`, 270 `func _() { f(-0x80000000) }`, 271 `func _() { 272 var x int32 = -0x80000000 273 _ = -x 274 }`, 275 }, 276 }) 277 } 278 279 func TestFalconArithmeticOverflow(t *testing.T) { 280 runTests(t, []testcase{ 281 { 282 "Addition without overflow.", 283 `func f(x, y int32) int32 { return x + y }`, 284 `func _() { f(100, 200) }`, 285 `func _() { _ = int32(100) + int32(200) }`, 286 }, 287 { 288 "Addition with overflow.", 289 `func f(x, y int32) int32 { return x + y }`, 290 `func _() { f(1<<30, 1<<30) }`, 291 `func _() { 292 var x, y int32 = 1 << 30, 1 << 30 293 _ = x + y 294 }`, 295 }, 296 { 297 "Conversion in range.", 298 `func f(x int) int8 { return int8(x) }`, 299 `func _() { f(123) }`, 300 `func _() { _ = int8(123) }`, 301 }, 302 { 303 "Conversion out of range.", 304 `func f(x int) int8 { return int8(x) }`, 305 `func _() { f(456) }`, 306 `func _() { 307 var x int = 456 308 _ = int8(x) 309 }`, 310 }, 311 }) 312 } 313 314 func TestFalconComplex(t *testing.T) { 315 runTests(t, []testcase{ 316 { 317 "Complex arithmetic (good).", 318 `func f(re, im float64, z complex128) byte { return "x"[int(real(complex(re, im)*complex(re, -im)-z))] }`, 319 `func _() { f(1, 2, 5+0i) }`, 320 `func _() { _ = "x"[int(real(complex(1, 2)*complex(1, -2)-(5+0i)))] }`, 321 }, 322 { 323 "Complex arithmetic (bad).", 324 `func f(re, im float64, z complex128) byte { return "x"[int(real(complex(re, im)*complex(re, -im)-z))] }`, 325 `func _() { f(1, 3, 5+0i) }`, 326 `func _() { 327 var ( 328 re, im float64 = 1, 3 329 z complex128 = 5 + 0i 330 ) 331 _ = "x"[int(real(complex(re, im)*complex(re, -im)-z))] 332 }`, 333 }, 334 }) 335 } 336 func TestFalconMisc(t *testing.T) { 337 runTests(t, []testcase{ 338 { 339 "Compound constant expression (good).", 340 `func f(x, y string, i, j int) byte { return x[i*len(y)+j] }`, 341 `func _() { f("abc", "xy", 2, -3) }`, 342 `func _() { _ = "abc"[2*len("xy")+-3] }`, 343 }, 344 { 345 "Compound constant expression (index out of range).", 346 `func f(x, y string, i, j int) byte { return x[i*len(y)+j] }`, 347 `func _() { f("abc", "xy", 4, -3) }`, 348 `func _() { 349 var ( 350 x, y string = "abc", "xy" 351 i, j int = 4, -3 352 ) 353 _ = x[i*len(y)+j] 354 }`, 355 }, 356 { 357 "Constraints within nested functions (good).", 358 `func f(x int) { _ = func() { _ = [1]int{}[x] } }`, 359 `func _() { f(0) }`, 360 `func _() { _ = func() { _ = [1]int{}[0] } }`, 361 }, 362 { 363 "Constraints within nested functions (bad).", 364 `func f(x int) { _ = func() { _ = [1]int{}[x] } }`, 365 `func _() { f(1) }`, 366 `func _() { 367 var x int = 1 368 _ = func() { _ = [1]int{}[x] } 369 }`, 370 }, 371 { 372 "Falcon violation rejects only the constant arguments (x, z).", 373 `func f(x, y, z string) string { return x[:2] + y + z[:2] }; var b string`, 374 `func _() { f("a", b, "c") }`, 375 `func _() { 376 var x, z string = "a", "c" 377 _ = x[:2] + b + z[:2] 378 }`, 379 }, 380 }) 381 }