cgen: add fixed array bounds checking for non-literal index (#8832)
parent
41a3b115a1
commit
15daeaeafa
8
TESTS.md
8
TESTS.md
|
@ -18,6 +18,11 @@ Tip: use `v -cc tcc` when compiling tests for speed.
|
|||
|
||||
General runnable tests for different features of the V compiler.
|
||||
|
||||
* `vlib/v/tests/inout/compiler_test.v`
|
||||
|
||||
Test output of running a V program matches an expected .out file.
|
||||
Check the source for how to test panics.
|
||||
|
||||
## Test building of actual V programs (examples, tools, V itself)
|
||||
|
||||
* `v build-tools`
|
||||
|
@ -41,11 +46,12 @@ This verifies that `_keep.v` files would be unchanged by `vfmt -w`.
|
|||
This checks all source files are formatted and prints a summary.
|
||||
This is not required.
|
||||
|
||||
## Other
|
||||
* `v test-fmt`
|
||||
|
||||
Test all files in the current directory are formatted.
|
||||
|
||||
## Markdown
|
||||
|
||||
* `v check-md -hide-warnings .`
|
||||
|
||||
Ensure that all .md files in the project are formatted properly,
|
||||
|
|
|
@ -274,3 +274,14 @@ pub fn is_atty(fd int) int {
|
|||
return C.isatty(fd)
|
||||
}
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn v_fixed_index(i int, len int) int {
|
||||
$if !no_bounds_checking ? {
|
||||
if i < 0 || i >= len {
|
||||
s := 'fixed array index out of range (index: $i, len: $len)'
|
||||
panic(s)
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
|
|
@ -4217,6 +4217,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
g.write(')')
|
||||
}
|
||||
else {
|
||||
// indexing
|
||||
sym := g.table.get_final_type_symbol(node.left_type)
|
||||
left_is_ptr := node.left_type.is_ptr()
|
||||
if sym.kind == .array {
|
||||
|
@ -4397,7 +4398,15 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
|||
g.expr(node.left)
|
||||
}
|
||||
g.write('[')
|
||||
g.expr(node.index)
|
||||
direct := g.fn_decl != 0 && g.fn_decl.is_direct_arr
|
||||
if direct || node.index is ast.IntegerLiteral {
|
||||
g.expr(node.index)
|
||||
} else {
|
||||
// bounds check
|
||||
g.write('v_fixed_index(')
|
||||
g.expr(node.index)
|
||||
g.write(', $info.size)')
|
||||
}
|
||||
g.write(']')
|
||||
if is_fn_index_call {
|
||||
g.write(')')
|
||||
|
|
|
@ -22,6 +22,7 @@ pub fn mark_used(mut the_table table.Table, pref &pref.Preferences, ast_files []
|
|||
'__new_array_with_default',
|
||||
'__new_array_with_array_default',
|
||||
'new_array_from_c_array',
|
||||
'v_fixed_index',
|
||||
'memdup',
|
||||
'vstrlen',
|
||||
'__as_cast',
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// .out file:
|
||||
// To test a panic, remove everything after the long `===` line
|
||||
// You can also remove the line with 'line:' e.g. for a builtin fn
|
||||
|
||||
import os
|
||||
import term
|
||||
import v.util
|
||||
|
@ -52,7 +56,7 @@ fn test_all() {
|
|||
n_found := normalize_panic_message(found, vroot)
|
||||
n_expected := normalize_panic_message(expected, vroot)
|
||||
if found.contains('================ V panic ================') {
|
||||
if n_found.contains(n_expected) {
|
||||
if n_found.starts_with(n_expected) {
|
||||
println(term.green('OK (panic)'))
|
||||
continue
|
||||
} else {
|
||||
|
@ -86,7 +90,10 @@ fn test_all() {
|
|||
|
||||
fn normalize_panic_message(message string, vroot string) string {
|
||||
mut msg := message.all_before('=========================================')
|
||||
msg = msg.replace(vroot + os.path_separator, '')
|
||||
// change windows to nix path
|
||||
s := vroot.replace(os.path_separator, '/')
|
||||
// remove vroot
|
||||
msg = msg.replace(s + '/', '')
|
||||
msg = msg.trim_space()
|
||||
return msg
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
1
|
||||
================ V panic ================
|
||||
module: builtin
|
||||
function: v_fixed_index()
|
||||
message: fixed array index out of range (index: 2, len: 2)
|
||||
file: vlib/builtin/builtin.c.v
|
|
@ -0,0 +1,4 @@
|
|||
a := [1,2]!
|
||||
println(a[0])
|
||||
i := 2
|
||||
_ = a[i]
|
|
@ -0,0 +1,5 @@
|
|||
================ V panic ================
|
||||
module: builtin
|
||||
function: slice()
|
||||
message: array.slice: slice bounds out of range (3 >= 2)
|
||||
file: vlib/builtin/array.v
|
|
@ -0,0 +1,3 @@
|
|||
a := [1,2]!
|
||||
i := 3
|
||||
_ = a[i..i]
|
Loading…
Reference in New Issue