1
- import os
2
1
import strings
3
2
4
3
// This program is built and run via Valgrind to ensure there are no leaks with -autofree
@@ -9,11 +8,13 @@ fn simple() {
9
8
println (nums_copy)
10
9
name := 'Peter' // string literals mustn't be freed
11
10
str_inter := 'hello, ${name} ' // concatenated strings must be freed
11
+ println (str_inter)
12
12
// nums.free() // this should result in a double free and a CI error
13
13
if true {
14
14
// test the freeing of local vars in a new scope
15
15
nums2 := [4 , 5 , 6 ]
16
16
str_inter2 := 'hello, ${name} '
17
+ println (str_inter2 )
17
18
println (nums2 )
18
19
}
19
20
arr := return_array ([])
@@ -119,6 +120,9 @@ fn reassign_str() {
119
120
mut s := 'a' + 'b'
120
121
s = 'x' + 'y' // 'a' + 'b' must be freed before the re-assignment
121
122
s = s + '!' // old s ref must be copied and freed after the assignment, since s is still used in the right expr
123
+ println (z)
124
+ println (x)
125
+ println (s)
122
126
}
123
127
124
128
struct Foo2 {
@@ -133,8 +137,11 @@ fn reassign_arr() {
133
137
mut foo := Foo2 {[10 , 20 , 30 ]}
134
138
foo.nums = [40 , 50 , 60 ] // same with struct fields
135
139
foo.nums = [70 , 80 , 90 ]
140
+ println (x)
136
141
// TODO: remove this once structs are freed automatically
137
- foo.nums.free ()
142
+ unsafe {
143
+ foo.nums.free ()
144
+ }
138
145
}
139
146
140
147
fn match_expr () string {
@@ -173,6 +180,7 @@ fn option_str() {
173
180
p = opt ('query:${q} ' ) or { break }
174
181
break
175
182
}
183
+ println (p)
176
184
}
177
185
178
186
fn return_error_with_freed_expr () ! string {
@@ -236,6 +244,7 @@ fn loop_map() {
236
244
237
245
fn free_map () {
238
246
nums := [1 , 2 , 3 ]
247
+ println (nums)
239
248
/*
240
249
nums2 := nums.map(it + handle_strings('a' + 'b', 'c'))
241
250
println(nums2)
@@ -247,6 +256,7 @@ fn free_inside_opt_block() {
247
256
get_string ('c' + 'd' ) // c+d must be freed before a+b
248
257
return
249
258
}
259
+ println (x)
250
260
}
251
261
252
262
fn free_before_return () {
@@ -265,12 +275,15 @@ fn free_before_return_bool() bool {
265
275
266
276
fn free_before_break () {
267
277
s := 'a' + 'b'
278
+ println (s)
268
279
for {
269
280
q := [1 , 2 , 3 ]
281
+ println (q)
270
282
break
271
283
}
272
284
for {
273
285
aa := [1 , 2 , 3 ]
286
+ println (aa)
274
287
if true {
275
288
// breaking should free only vars in the closest for loop's scope
276
289
// `qq`, not `s`
@@ -279,12 +292,14 @@ fn free_before_break() {
279
292
// nested 1
280
293
for {
281
294
bb := [4 , 5 , 6 ]
295
+ println (bb)
282
296
if true {
283
297
break
284
298
}
285
299
// nested 2
286
300
for {
287
301
cc := [7 , 8 , 9 ]
302
+ println (cc)
288
303
if true {
289
304
if true {
290
305
break
@@ -298,6 +313,7 @@ fn free_before_break() {
298
313
for {
299
314
i++
300
315
qq := [1 , 2 , 3 ]
316
+ println (qq)
301
317
if i > 10 {
302
318
break
303
319
}
@@ -336,6 +352,7 @@ fn get_user2() User {
336
352
fn string_array_get () {
337
353
s := ['a' , 'b' , 'c' ]
338
354
x := s[0 ]
355
+ println (x)
339
356
println (s)
340
357
}
341
358
@@ -379,6 +396,7 @@ fn parse_header1(s string) !string {
379
396
fn advanced_options () {
380
397
s := parse_header0 ('foo:bar' ) or { return }
381
398
s2 := parse_header1 ('foo:bar' ) or { return }
399
+ _ := s.len + s2 .len // avoid warning for unused variables
382
400
// TODO: fix -autofree, so that it adds this free automatically:
383
401
unsafe { s2 .free () }
384
402
}
@@ -400,13 +418,16 @@ fn main() {
400
418
if_cond ()
401
419
addition_with_tmp_expr ()
402
420
q := if_expr ()
421
+ println (q)
403
422
s := return_if_expr ()
423
+ println (s)
404
424
free_inside_opt_block ()
405
425
comptime_if ()
406
426
free_before_return ()
407
427
free_before_return_bool ()
408
428
free_before_break ()
409
429
s2 := return_sb_str ()
430
+ println (s2 )
410
431
// free_map()
411
432
// loop_map()
412
433
advanced_options ()
0 commit comments