vxx2 / vlib / v / tests / autofree_error_sentinel_test.v
35 lines · 31 sloc · 1.04 KB · 0b1ee86f742567f2fcb3c534b0a49a6dddba36ab
Raw
1// vtest build: !sanitize-address-gcc && !sanitize-address-clang
2// vtest vflags: -autofree -gc none
3// Regression test for the `-autofree` double-free of the `error_sentinel` singleton
4// (review on https://github.com/vlang/v/pull/27544). Under `-autofree`, const cleanup
5// frees every `IError` const's boxed object; the sentinel can also be copied/re-exported,
6// so its shared `MessageError` object must be exempted from `free()` like `none__`.
7// `-gc none` is required so `free()` actually returns memory (a double free would abort
8// at program cleanup) instead of being a GC no-op.
9
10const my_err = error_sentinel // re-export: shares the same boxed object
11
12fn find(x int) !int {
13 if x < 0 {
14 return error_sentinel
15 }
16 return x
17}
18
19fn alias_find(x int) !int {
20 if x < 0 {
21 return my_err
22 }
23 return x
24}
25
26fn test_error_sentinel_autofree_no_double_free() {
27 mut misses := 0
28 for i := -50; i < 50; i++ {
29 find(i) or { misses++ }
30 alias_find(i) or { misses++ }
31 }
32 assert misses == 100
33 assert my_err.msg() == 'error'
34 assert error_sentinel.msg() == 'error'
35}
36