parser, cgen: fix static and volatile var deref (fix #24778) (fix #24779) (#24807)

This commit is contained in:
Felipe Pena 2025-06-29 01:29:29 -03:00 committed by GitHub
parent bea73f7a3b
commit b909e2eb37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 55 additions and 2 deletions

View file

@ -956,6 +956,8 @@ fn (t Tree) var(node ast.Var) &Node {
obj.add_terse('expr', t.expr(node.expr)) obj.add_terse('expr', t.expr(node.expr))
obj.add_terse('is_arg', t.bool_node(node.is_arg)) obj.add_terse('is_arg', t.bool_node(node.is_arg))
obj.add_terse('is_mut', t.bool_node(node.is_mut)) obj.add_terse('is_mut', t.bool_node(node.is_mut))
obj.add_terse('is_static', t.bool_node(node.is_static))
obj.add_terse('is_volatile', t.bool_node(node.is_volatile))
obj.add('is_used', t.bool_node(node.is_used)) obj.add('is_used', t.bool_node(node.is_used))
obj.add('is_changed', t.bool_node(node.is_changed)) obj.add('is_changed', t.bool_node(node.is_changed))
obj.add_terse('ct_type_var', t.enum_node(node.ct_type_var)) obj.add_terse('ct_type_var', t.enum_node(node.ct_type_var))

View file

@ -904,6 +904,8 @@ pub:
name string name string
share ShareType share ShareType
is_mut bool is_mut bool
is_static bool
is_volatile bool
is_autofree_tmp bool is_autofree_tmp bool
is_inherited bool is_inherited bool
has_inherited bool has_inherited bool

View file

@ -179,9 +179,15 @@ fn (mut g Gen) expr_with_opt(expr ast.Expr, expr_typ ast.Type, ret_typ ast.Type)
fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
mut node := unsafe { node_ } mut node := unsafe { node_ }
if node.is_static { if node.is_static {
g.write('static ') is_defer_var := node.left[0] is ast.Ident && node.left[0].name in g.defer_vars
if is_defer_var && node.op == .decl_assign {
return
}
if !is_defer_var {
g.write('static ')
}
} }
if node.is_volatile { if node.is_volatile && node.left[0] is ast.Ident && node.left[0].name !in g.defer_vars {
g.write('volatile ') g.write('volatile ')
} }
mut return_type := ast.void_type mut return_type := ast.void_type

View file

@ -444,6 +444,12 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
} }
info := var.obj as ast.Var info := var.obj as ast.Var
if g.table.sym(info.typ).kind != .function { if g.table.sym(info.typ).kind != .function {
if info.is_static {
g.write('static ')
}
if info.is_volatile {
g.write('volatile ')
}
g.writeln('${g.styp(info.typ)}${deref} ${c_name(var.name)};') g.writeln('${g.styp(info.typ)}${deref} ${c_name(var.name)};')
} }
} }

View file

@ -224,6 +224,8 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr) ast.Stmt {
expr: if left.len == right.len { right[i] } else { ast.empty_expr } expr: if left.len == right.len { right[i] } else { ast.empty_expr }
share: share share: share
is_mut: lx.is_mut || p.inside_for is_mut: lx.is_mut || p.inside_for
is_static: is_static
is_volatile: is_volatile
pos: lx.pos pos: lx.pos
is_stack_obj: p.inside_for is_stack_obj: p.inside_for
} }

View file

@ -0,0 +1,35 @@
@[unsafe]
fn g() {
mut static levels := 0
levels++
defer { levels-- }
}
fn f(depth int) {
if depth == 0 {
return
}
unsafe {
mut static levels := 0
levels++
defer { levels-- }
if depth == 3 {
assert levels == 1
}
if depth == 2 {
assert levels == 2
}
if depth == 1 {
assert levels == 3
}
println('levels: ${levels} | depth: ${depth}')
}
f(depth - 1)
}
fn test_main() {
f(3)
f(3)
unsafe { g() }
}