| 1 | fn test_ptr_arithmetic() { |
| 2 | unsafe { |
| 3 | // Do NOT move this outside unsafe{}. |
| 4 | // It causes too much churn in CI when new checks are implemented. |
| 5 | // If you want to implement a specific failing test, do so inside |
| 6 | // vlib/v/checker/tests/ , NOT here. |
| 7 | v := 4 |
| 8 | mut p := &v |
| 9 | p++ |
| 10 | p += 2 |
| 11 | p = p - 1 |
| 12 | assert ptr_str(p) == ptr_str(&v + 2) |
| 13 | p = p + 1 |
| 14 | assert ptr_str(p) == ptr_str(&v + 3) |
| 15 | r := p++ |
| 16 | assert ptr_str(r) == ptr_str(&v + 3) |
| 17 | assert ptr_str(p) == ptr_str(&v + 4) |
| 18 | } |
| 19 | } |
| 20 | |
| 21 | fn test_ptr_arithmetic_over_byteptr() { |
| 22 | // byteptr, voidptr, charptr are handled differently |
| 23 | mut q := unsafe { &u8(10) } |
| 24 | unsafe { |
| 25 | q -= 2 |
| 26 | q = q + 1 |
| 27 | } |
| 28 | assert u64(q) == u64(unsafe { &u8(9) }) |
| 29 | s := unsafe { q - 1 } |
| 30 | assert u64(s) == u64(unsafe { &u8(8) }) |
| 31 | unsafe { |
| 32 | q++ |
| 33 | q++ |
| 34 | q-- |
| 35 | } |
| 36 | assert u64(q) == u64(unsafe { &u8(10) }) |
| 37 | } |
| 38 | |
| 39 | struct Abc { |
| 40 | mut: |
| 41 | x int |
| 42 | y int |
| 43 | z int |
| 44 | } |
| 45 | |
| 46 | fn test_ptr_arithmetic_over_struct() { |
| 47 | mut a := [3]Abc{} |
| 48 | a[0].x = 10 |
| 49 | a[1].x = 100 |
| 50 | a[2].x = 1000 |
| 51 | mut pa := unsafe { &a[0] } |
| 52 | assert pa == unsafe { &a[0] } |
| 53 | unsafe { |
| 54 | assert pa.x == 10 |
| 55 | pa++ |
| 56 | assert u64(pa) - u64(&a[0]) == sizeof(Abc) |
| 57 | assert pa.x == 100 |
| 58 | pa++ |
| 59 | assert u64(pa) - u64(&a[0]) == 2 * sizeof(Abc) |
| 60 | assert pa.x == 1000 |
| 61 | pa-- |
| 62 | assert pa.x == 100 |
| 63 | pa-- |
| 64 | assert pa.x == 10 |
| 65 | pa += 2 |
| 66 | assert pa.x == 1000 |
| 67 | pa -= 2 |
| 68 | } |
| 69 | assert pa == unsafe { &a[0] } |
| 70 | } |
| 71 | |
| 72 | fn test_ptr_infix_arithmetic_over_struct() { |
| 73 | mut a := [3]Abc{} |
| 74 | a[0].x = 10 |
| 75 | a[1].x = 100 |
| 76 | a[2].x = 1000 |
| 77 | unsafe { |
| 78 | pa := &a[0] |
| 79 | next := pa + 1 |
| 80 | assert next.x == 100 |
| 81 | last := next + 1 |
| 82 | assert last.x == 1000 |
| 83 | back := last - 2 |
| 84 | assert back.x == 10 |
| 85 | |
| 86 | refs := [&a[0], &a[1], &a[2]] |
| 87 | ppa := &refs[0] |
| 88 | next_ptr := ppa + 1 |
| 89 | assert (*next_ptr).x == 100 |
| 90 | last_ptr := next_ptr + 1 |
| 91 | assert (*last_ptr).x == 1000 |
| 92 | back_ptr := last_ptr - 2 |
| 93 | assert (*back_ptr).x == 10 |
| 94 | } |
| 95 | } |
| 96 | |