Skip to content

Incorrect function reference captured in closure leads to crash #26049

Description

@Yv-vY

This bug follows on #25940

V version: V 0.4.12 60f7c81, press to see full `v doctor` output
V full version V 0.4.12 caf7d41.60f7c81
OS linux, Linux version 6.17.12-300.fc43.x86_64 (mockbuild@008798550d8d49b8909ac02baf9be783) (gcc (GCC) 15.2.1 20251111 (Red Hat 15.2.1-4), GNU ld version 2.45.1-1.fc43) #1 SMP PREEMPT_DYNAMIC Sat Dec 13 05:06:24 UTC 2025
Processor 16 cpus, 64bit, little endian, AMD Ryzen 7 7800X3D 8-Core Processor
Memory 25.77GB/30.94GB
V executable /home/yann/Apps/v/v
V last modified time 2025-12-20 09:31:02
V home dir OK, value: /home/yann/Apps/v
VMODULES OK, value: /home/yann/.vmodules
VTMP OK, value: /tmp/v_1000
Current working dir OK, value: /home/yann/devel/perso/v/bug_function_ref_closure
Git version git version 2.52.0
V git status weekly.2025.43-352-g60f7c815
.git/config present true
cc version cc (GCC) 15.2.1 20251211 (Red Hat 15.2.1-5)
gcc version gcc (GCC) 15.2.1 20251211 (Red Hat 15.2.1-5)
clang version clang version 21.1.7 (Fedora 21.1.7-1.fc43)
tcc version tcc version 0.9.28rc 2025-02-13 HEAD@f8bd136d (x86_64 Linux)
tcc git status thirdparty-linux-amd64 696c1d84
emcc version N/A
glibc version ldd (GNU libc) 2.42

What did you do?
./v -g -o vdbg cmd/v && ./vdbg main.v && main

module main

fn f_a() {
	println('a')
}

fn main() {
	f := f_a
	ref := &f
	println('ref=0x${ptr_str(ref)}')

	handler := fn [ref] () { // ref_fn is captured as a direct function pointer (*fn) instead of a pointer to a function (**fn)
		println('in closure: ref=0x${ptr_str(ref)}')
		deref_fn := *ref
		println('in closure: deref=0x${ptr_str(deref_fn)}')
		deref_fn()
		}

	f()
	deref := *ref
	println('deref=0x${ptr_str(deref)}')
	deref()
	handler()
}

What did you see?

ref=0x7ffeee063e48
a
deref=0x6154a2
a
in closure: ref=0x7ffeee063e48
in closure: deref=0x7ffeee063e48
0x7ffeee063e48: at ???: RUNTIME ERROR: invalid memory access
/tmp/v_1000/main.01KCXM2D5X0V8P114VXM772JFX.tmp.c:5182: by main__main
/tmp/v_1000/main.01KCXM2D5X0V8P114VXM772JFX.tmp.c:5260: by main

What did you expect to see?

A successful call to the reference of the function captured in the closure.

Additional investigation

The generated code for the closure is correct but for the type of the function reference in the anonymous function structure:

struct _V_anon_fn_552ebdfa8c8536a3__538_Ctx {
	void (*ref) ();
};

Should be:

struct _V_anon_fn_552ebdfa8c8536a3__538_Ctx {
	void (**ref) ();
};

This only change solves the issue.

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions