From bc582027e55e8f43058d6851460cd13939e6c73a Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 23 Apr 2026 18:15:37 +0300 Subject: [PATCH] cgen: fix "builder error / C error. This should never happen.", when calling C.xcb_setup_roots_iterator() from XCB library (fixes #16906) --- .gitignore | 1 + .../headerless_c_struct_return.c.must_have | 2 ++ .../c/testdata/headerless_c_struct_return.out | 1 + .../c/testdata/headerless_c_struct_return.vv | 35 +++++++++++++++++++ .../headerless_c_struct_return_impl.c | 31 ++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 vlib/v/gen/c/testdata/headerless_c_struct_return.c.must_have create mode 100644 vlib/v/gen/c/testdata/headerless_c_struct_return.out create mode 100644 vlib/v/gen/c/testdata/headerless_c_struct_return.vv create mode 100644 vlib/v/gen/c/testdata/headerless_c_struct_return_impl.c diff --git a/.gitignore b/.gitignore index 6b439b551..2e39368c1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ # unignore c codegen testdata files !vlib/v/gen/c/testdata/*.vv !vlib/v/gen/c/testdata/*.out +!vlib/v/gen/c/testdata/*.c !vlib/v/gen/c/testdata/*.c.must_have # unignore vlib/x/markdown diff --git a/vlib/v/gen/c/testdata/headerless_c_struct_return.c.must_have b/vlib/v/gen/c/testdata/headerless_c_struct_return.c.must_have new file mode 100644 index 000000000..e0d41efee --- /dev/null +++ b/vlib/v/gen/c/testdata/headerless_c_struct_return.c.must_have @@ -0,0 +1,2 @@ +extern main__ScreenIter setup_roots_iterator(main__Setup* r); +main__ScreenIter iter = setup_roots_iterator(&setup); diff --git a/vlib/v/gen/c/testdata/headerless_c_struct_return.out b/vlib/v/gen/c/testdata/headerless_c_struct_return.out new file mode 100644 index 000000000..f432d7ff4 --- /dev/null +++ b/vlib/v/gen/c/testdata/headerless_c_struct_return.out @@ -0,0 +1 @@ +5|7|641 diff --git a/vlib/v/gen/c/testdata/headerless_c_struct_return.vv b/vlib/v/gen/c/testdata/headerless_c_struct_return.vv new file mode 100644 index 000000000..17dc8d7e1 --- /dev/null +++ b/vlib/v/gen/c/testdata/headerless_c_struct_return.vv @@ -0,0 +1,35 @@ +module main + +#flag @VMODROOT/vlib/v/gen/c/testdata/headerless_c_struct_return_impl.c + +type Keycode = u8 + +struct Setup { + status u8 + min_keycode Keycode + max_keycode Keycode + pad1 [4]u8 +} + +struct Screen { + width u16 +} + +struct ScreenIter { + data &Screen + rem int + index int +} + +fn C.setup_roots_iterator(r &Setup) ScreenIter + +fn main() { + setup := Setup{ + status: 3 + min_keycode: 4 + max_keycode: 9 + pad1: [u8(1), 2, 3, 4]! + } + iter := C.setup_roots_iterator(&setup) + println('${iter.rem}|${iter.index}|${iter.data.width}') +} diff --git a/vlib/v/gen/c/testdata/headerless_c_struct_return_impl.c b/vlib/v/gen/c/testdata/headerless_c_struct_return_impl.c new file mode 100644 index 000000000..4ef4e1ab7 --- /dev/null +++ b/vlib/v/gen/c/testdata/headerless_c_struct_return_impl.c @@ -0,0 +1,31 @@ +typedef unsigned char u8; +typedef unsigned short u16; +typedef u8 Array_fixed_u8_4[4]; + +typedef struct main__Setup { + u8 status; + u8 min_keycode; + u8 max_keycode; + Array_fixed_u8_4 pad1; +} main__Setup; + +typedef struct main__Screen { + u16 width; +} main__Screen; + +typedef struct main__ScreenIter { + main__Screen* data; + int rem; + int index; +} main__ScreenIter; + +main__ScreenIter setup_roots_iterator(main__Setup* setup) { + static main__Screen screen; + screen.width = (u16)(640 + setup->pad1[0]); + main__ScreenIter iter = { + .data = &screen, + .rem = (int)(setup->max_keycode - setup->min_keycode), + .index = (int)(setup->status + setup->pad1[3]), + }; + return iter; +} -- 2.39.5