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