Here is an example with an out-of-bounds array subscript, run with HAVM.
let type int_array = array of int var foo := int_array [10] of 3 in /* Out-of-bounds access. */ foo[20] end
$ tc --bounds-checks-add -A subscript-read.tig /* == Abstract Syntax Tree. == */ primitive print(string_0 : string) primitive print_err(string_1 : string) primitive print_int(int_2 : int) primitive flush() primitive getchar() : string primitive ord(string_3 : string) : int primitive chr(code_4 : int) : string primitive size(string_5 : string) : int primitive streq(s1_6 : string, s2_7 : string) : int primitive strcmp(s1_8 : string, s2_9 : string) : int primitive substring(string_10 : string, start_11 : int, length_12 : int) : string primitive concat(fst_13 : string, snd_14 : string) : string primitive not(boolean_15 : int) : int primitive exit(status_16 : int) function _main() = let type __int_array = array of int type _int_array = { arr : __int_array, size : int } function _check_bounds(a : _int_array, index : int, location : string) : int = ( (if (if (index < 0) then 1 else ((index >= a.size) <> 0)) then ( print_err(location); print_err(": array index out of bounds.\n"); exit(120) ) else ()); index ) in ( let type _box_int_array_17 = { arr : int_array_17, size : int } type int_array_17 = array of int var foo_18 := let var _size := 10 in _box_int_array_17 { arr = int_array_17 [_size] of 3, size = _size } end in foo_18.arr[_check_bounds(_cast(foo_18, _int_array), 20, "1.1")] end; () ) end
$ tc --bounds-checks-add -L subscript-read.tig >subscript-read.lir
$ havm subscript-read.lir error→1.1: array index out of bounds. ⇒120
And here is an example with an out-of-bounds assignment to an array cell, tested with Nolimips.
let type int_array = array of int var foo := int_array [10] of 3 in /* Out-of-bounds assignment. */ foo[42] := 51 end
$ tc --bounds-checks-add -A subscript-write.tig /* == Abstract Syntax Tree. == */ primitive print(string_0 : string) primitive print_err(string_1 : string) primitive print_int(int_2 : int) primitive flush() primitive getchar() : string primitive ord(string_3 : string) : int primitive chr(code_4 : int) : string primitive size(string_5 : string) : int primitive streq(s1_6 : string, s2_7 : string) : int primitive strcmp(s1_8 : string, s2_9 : string) : int primitive substring(string_10 : string, start_11 : int, length_12 : int) : string primitive concat(fst_13 : string, snd_14 : string) : string primitive not(boolean_15 : int) : int primitive exit(status_16 : int) function _main() = let type __int_array = array of int type _int_array = { arr : __int_array, size : int } function _check_bounds(a : _int_array, index : int, location : string) : int = ( (if (if (index < 0) then 1 else ((index >= a.size) <> 0)) then ( print_err(location); print_err(": array index out of bounds.\n"); exit(120) ) else ()); index ) in ( let type _box_int_array_17 = { arr : int_array_17, size : int } type int_array_17 = array of int var foo_18 := let var _size := 10 in _box_int_array_17 { arr = int_array_17 [_size] of 3, size = _size } end in (foo_18.arr[_check_bounds(_cast(foo_18, _int_array), 42, "1.1")] := 51) end; () ) end
$ tc --bounds-checks-add -S subscript-write.tig >subscript-write.s
$ nolimips -l nolimips -Nue subscript-write.s error→1.1: array index out of bounds. ⇒120