mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
memory: free_scope_vars()
This commit is contained in:
parent
bb76e5da91
commit
60fbceea43
@ -451,7 +451,7 @@ fn (p mut Parser) parse(pass Pass) {
|
||||
}
|
||||
p.fgen_nl()
|
||||
p.builtin_mod = p.mod == 'builtin'
|
||||
p.can_chash = p.mod in ['parser', 'gg2', 'ui', 'uiold', 'darwin', 'clipboard', 'webview'] // TODO tmp remove
|
||||
p.can_chash = p.mod in ['parser', 'gg2', 'ui', 'uiold', 'darwin', 'clipboard', 'webview', 'gen'] // TODO tmp remove
|
||||
// Import pass - the first and the smallest pass that only analyzes imports
|
||||
// if we are a building module get the full module name from v.mod
|
||||
fq_mod := if p.pref.build_mode == .build_module && p.v.pref.mod.ends_with(p.mod) { p.v.pref.mod }
|
||||
|
@ -662,14 +662,7 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||
g.stmts(it.stmts)
|
||||
// ////////////
|
||||
if g.autofree {
|
||||
scope := g.file.scope.innermost(it.pos.pos - 1)
|
||||
for _, var in scope.vars {
|
||||
sym := g.table.get_type_symbol(var.typ)
|
||||
if sym.kind == .array && !table.type_is_optional(var.typ) {
|
||||
g.writeln('array_free($var.name); // autofree')
|
||||
}
|
||||
// println(var.name)
|
||||
}
|
||||
g.free_scope_vars(it.pos.pos - 1)
|
||||
}
|
||||
// /////////
|
||||
if is_main {
|
||||
@ -685,6 +678,30 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||
g.fn_decl = 0
|
||||
}
|
||||
|
||||
fn (g mut Gen) free_scope_vars(pos int) {
|
||||
scope := g.file.scope.innermost(pos)
|
||||
for _, var in scope.vars {
|
||||
sym := g.table.get_type_symbol(var.typ)
|
||||
if sym.kind == .array && !table.type_is_optional(var.typ) {
|
||||
g.writeln('array_free($var.name); // autofreed')
|
||||
}
|
||||
if sym.kind == .string && !table.type_is_optional(var.typ) {
|
||||
// Don't free simple string literals.
|
||||
t := typeof(var.expr)
|
||||
match var.expr {
|
||||
ast.StringLiteral {
|
||||
g.writeln('// str literal')
|
||||
continue
|
||||
}
|
||||
else {
|
||||
g.writeln('// other' + t)
|
||||
}
|
||||
}
|
||||
g.writeln('string_free($var.name); // autofreed')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (g mut Gen) fn_args(args []table.Arg, is_variadic bool) {
|
||||
no_names := args.len > 0 && args[0].name == 'arg_1'
|
||||
for i, arg in args {
|
||||
|
@ -7,10 +7,16 @@ fn return_array(array_arg []string) []int { // array argument must not be freed
|
||||
|
||||
fn foo() {
|
||||
nums := [1, 2, 3] // local array must be freed
|
||||
nums_copy := nums // array assignments call .clone()
|
||||
println(nums)
|
||||
|
||||
nums_copy := nums // array assignments call .clone()
|
||||
println(nums_copy)
|
||||
// nums.free() // this should result in a double free and a CI error
|
||||
|
||||
name := 'Peter' // string literals mustn't be freed
|
||||
str_inter := 'hello, $name' // concatenated strings must be freed
|
||||
|
||||
|
||||
//nums.free() // this should result in a double free and a CI error
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -31,8 +31,9 @@ fn test_all() {
|
||||
for test in tests {
|
||||
bench.step()
|
||||
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 -b v2 $wrkdir/x.v') or {
|
||||
res := os.exec('$vexe -verbose=3 -b v2 -csource keep -cg $wrkdir/x.v') or {
|
||||
bench.fail()
|
||||
eprintln(bench.step_message_fail('valgrind $test failed'))
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user