Skip to content

Commit f79867d

Browse files
authored
cgen: fix fntype unwrap on ifguard (fix #25911) (#25914)
1 parent 050a023 commit f79867d

File tree

4 files changed

+57
-27
lines changed

4 files changed

+57
-27
lines changed

vlib/v/gen/c/assign.v

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -799,32 +799,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
799799
ret_styp := g.styp(g.unwrap_generic(val_type))
800800
g.write('${ret_styp} ${fn_name}')
801801
} else {
802-
ret_styp := g.styp(right_sym.info.func.return_type)
803-
mut call_conv := ''
804-
mut msvc_call_conv := ''
805-
for attr in right_sym.info.func.attrs {
806-
match attr.name {
807-
'callconv' {
808-
if g.is_cc_msvc {
809-
msvc_call_conv = '__${attr.arg} '
810-
} else {
811-
call_conv = '${attr.arg}'
812-
}
813-
}
814-
else {}
815-
}
816-
}
817-
call_conv_attribute_suffix := if call_conv.len != 0 {
818-
'__attribute__((${call_conv}))'
819-
} else {
820-
''
821-
}
822-
g.write('${ret_styp} (${msvc_call_conv}*${fn_name}) (')
823-
def_pos := g.definitions.len
824-
g.fn_decl_params(right_sym.info.func.params, unsafe { nil }, false,
825-
false)
826-
g.definitions.go_back(g.definitions.len - def_pos)
827-
g.write(')${call_conv_attribute_suffix}')
802+
g.write_fntype_decl(fn_name, right_sym.info)
828803
}
829804
} else {
830805
if is_decl {

vlib/v/gen/c/fn.v

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3050,3 +3050,31 @@ fn (mut g Gen) write_fn_attrs(attrs []ast.Attr) string {
30503050
fn call_convention_attribute(cconvention string, is_cc_msvc bool) string {
30513051
return if is_cc_msvc { '__${cconvention} ' } else { '__attribute__((${cconvention})) ' }
30523052
}
3053+
3054+
fn (mut g Gen) write_fntype_decl(fn_name string, info ast.FnType) {
3055+
ret_styp := g.styp(info.func.return_type)
3056+
mut call_conv := ''
3057+
mut msvc_call_conv := ''
3058+
for attr in info.func.attrs {
3059+
match attr.name {
3060+
'callconv' {
3061+
if g.is_cc_msvc {
3062+
msvc_call_conv = '__${attr.arg} '
3063+
} else {
3064+
call_conv = '${attr.arg}'
3065+
}
3066+
}
3067+
else {}
3068+
}
3069+
}
3070+
call_conv_attribute_suffix := if call_conv.len != 0 {
3071+
'__attribute__((${call_conv}))'
3072+
} else {
3073+
''
3074+
}
3075+
g.write('${ret_styp} (${msvc_call_conv}*${fn_name}) (')
3076+
def_pos := g.definitions.len
3077+
g.fn_decl_params(info.func.params, unsafe { nil }, false, false)
3078+
g.definitions.go_back(g.definitions.len - def_pos)
3079+
g.write(')${call_conv_attribute_suffix}')
3080+
}

vlib/v/gen/c/if.v

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,13 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
395395
} else {
396396
'-> '
397397
}
398-
g.writeln('\t${base_type} ${left_var_name} = *(${base_type}*)${var_name}${dot_or_ptr}data;')
398+
expr_sym := g.table.sym(branch.cond.expr_type)
399+
if expr_sym.info is ast.FnType {
400+
g.write_fntype_decl(left_var_name, expr_sym.info)
401+
} else {
402+
g.write('\t${base_type} ${left_var_name}')
403+
}
404+
g.writeln(' = *(${base_type}*)${var_name}${dot_or_ptr}data;')
399405
}
400406
} else if branch.cond.vars.len > 1 {
401407
sym := g.table.sym(branch.cond.expr_type)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
type MyFn = fn ()
2+
3+
fn hello() {
4+
println(@FN)
5+
}
6+
7+
fn get_ptr() ?&MyFn {
8+
return &hello
9+
}
10+
11+
fn test_main() {
12+
if p := get_ptr() {
13+
assert voidptr(p) == voidptr(hello)
14+
dump(p)
15+
p()
16+
}
17+
18+
p2 := get_ptr() or { return }
19+
p2()
20+
assert voidptr(p2) == voidptr(hello)
21+
}

0 commit comments

Comments
 (0)