diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index d8cdd8315b..5f79417e36 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -53,6 +53,7 @@ struct Gen { typedefs2 strings.Builder definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) inits strings.Builder // contents of `void _vinit(){}` + cleanups strings.Builder // contents of `void _vcleanup(){}` gowrappers strings.Builder // all go callsite wrappers stringliterals strings.Builder // all string literals (they depend on tos3() beeing defined auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs @@ -121,6 +122,7 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string auto_str_funcs: strings.new_builder(100) comptime_defines: strings.new_builder(100) inits: strings.new_builder(100) + cleanups: strings.new_builder(100) pcs_declarations: strings.new_builder(100) hotcode_definitions: strings.new_builder(100) table: table @@ -2292,8 +2294,18 @@ fn (mut g Gen) const_decl_init_later(name, val string, typ table.Type) { // Initialize more complex consts in `void _vinit(){}` // (C doesn't allow init expressions that can't be resolved at compile time). styp := g.typ(typ) - g.definitions.writeln('$styp _const_$name; // inited later') - g.inits.writeln('\t_const_$name = $val;') + // + cname := '_const_$name' + g.definitions.writeln('$styp $cname; // inited later') + g.inits.writeln('\t$cname = $val;') + if g.pref.autofree { + if styp.starts_with('array_') { + g.cleanups.writeln('\tarray_free(&$cname);') + } + if styp == 'string' { + g.cleanups.writeln('\tstring_free(&$cname);') + } + } } fn (mut g Gen) go_back_out(n int) { @@ -2496,26 +2508,7 @@ fn (mut g Gen) write_init_function() { fn_vcleanup_start_pos := g.out.len g.writeln('void _vcleanup() {') // g.writeln('puts("cleaning up...");') - if g.is_importing_os() { - g.writeln('array_free(&_const_os__args);') - g.writeln('string_free(&_const_os__wd_at_startup);') - } - // - g.writeln('array_free(&_const_math__bits__de_bruijn32tab);') - g.writeln('array_free(&_const_math__bits__de_bruijn64tab);') - g.writeln('array_free(&_const_math__bits__ntz_8_tab);') - g.writeln('array_free(&_const_math__bits__pop_8_tab);') - g.writeln('array_free(&_const_math__bits__rev_8_tab);') - g.writeln('array_free(&_const_math__bits__len_8_tab);') - g.writeln('array_free(&_const_strconv__ftoa__ten_pow_table_32);') - g.writeln('array_free(&_const_strconv__ftoa__ten_pow_table_64);') - g.writeln('array_free(&_const_strconv__ftoa__powers_of_10);') - g.writeln('array_free(&_const_strconv__ftoa__pow5_split_32);') - g.writeln('array_free(&_const_strconv__ftoa__pow5_inv_split_32);') - g.writeln('array_free(&_const_strconv__ftoa__pow5_split_64);') - g.writeln('array_free(&_const_strconv__ftoa__pow5_inv_split_64);') - g.writeln('array_free(&_const_strconv__dec_round);') - // + g.writeln(g.cleanups.str()) g.writeln('}') if g.pref.printfn_list.len > 0 && '_vcleanup' in g.pref.printfn_list { println(g.out.after(fn_vcleanup_start_pos)) diff --git a/vlib/v/tests/valgrind/valgrind_test.v b/vlib/v/tests/valgrind/valgrind_test.v index 5c26b9f658..9739110e36 100644 --- a/vlib/v/tests/valgrind/valgrind_test.v +++ b/vlib/v/tests/valgrind/valgrind_test.v @@ -2,11 +2,12 @@ import os import term import benchmark +[if verbose] +fn vprintln(s string) { + eprintln(s) +} + fn test_all() { - $if tinyc { - eprintln('Temporarily disabled for tcc, till the generated C code works with tcc.') - exit(0) - } if os.user_os() != 'linux' && os.getenv('FORCE_VALGRIND_TEST').len == 0 { eprintln('Valgrind tests can only be run reliably on Linux for now.') eprintln('You can still do it by setting FORCE_VALGRIND_TEST=1 .') @@ -37,7 +38,9 @@ fn test_all() { full_test_path := os.real_path(test) println('x.v: $wrkdir/x.v') os.system('cp ${dir}/${test} $wrkdir/x.v') // cant run .vv file - res := os.exec('$vexe -cflags "-w" -verbose=3 -autofree -csource keep -cg $wrkdir/x.v') or { + compile_cmd := '$vexe -cflags "-w" -verbose=3 -autofree -keepc -cg $wrkdir/x.v' + vprintln('compile cmd: $compile_cmd') + res := os.exec(compile_cmd) or { bench.fail() eprintln(bench.step_message_fail('valgrind $test failed')) continue @@ -48,7 +51,9 @@ fn test_all() { eprintln(res.output) continue } - valgrind_res := os.exec('valgrind --error-exitcode=1 --leak-check=full $wrkdir/x') or { + valgrind_cmd := 'valgrind --error-exitcode=1 --leak-check=full $wrkdir/x' + vprintln('valgrind cmd: $valgrind_cmd') + valgrind_res := os.exec(valgrind_cmd) or { bench.fail() eprintln(bench.step_message_fail('valgrind could not be executed')) continue