From b60966cd10425e14b37c44e26c3fef429bc7e3b3 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 5 Mar 2025 14:16:25 -0300 Subject: [PATCH] cgen: fix interface method list ordering to make test buildable with `g++` (fix #23701) (#23870) --- vlib/v/gen/c/cgen.v | 11 ++++++++--- .../c/testdata/iface_method_order.c.must_have | 18 ++++++++++++++++++ vlib/v/gen/c/testdata/iface_method_order.vv | 18 ++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 vlib/v/gen/c/testdata/iface_method_order.c.must_have create mode 100644 vlib/v/gen/c/testdata/iface_method_order.vv diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 7b219f6463..b192e8b27c 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -7533,7 +7533,8 @@ fn (mut g Gen) interface_table() string { methods_struct_name := 'struct _${interface_name}_interface_methods' mut methods_struct_def := strings.new_builder(100) methods_struct_def.writeln('${methods_struct_name} {') - inter_methods := inter_info.get_methods() + mut inter_methods := inter_info.get_methods() + inter_methods.sort(a < b) mut methodidx := map[string]int{} for k, method_name in inter_methods { method := isym.find_method_with_generic_parent(method_name) or { continue } @@ -7664,7 +7665,9 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}* methods_struct.writeln('\t{') } if st == ast.voidptr_type || st == ast.nil_type { - for mname, _ in methodidx { + mut mnames := methodidx.keys() + mnames.sort(a < b) + for mname in mnames { if g.pref.build_mode != .build_module { methods_struct.writeln('\t\t._method_${c_fn_name(mname)} = (void*) 0,') } @@ -7721,7 +7724,9 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}* } } - for method in methods { + mut ordered_methods := methods.clone() + ordered_methods.sort(a.name < b.name) + for method in ordered_methods { mut name := method.name if method.generic_names.len > 0 && inter_info.parent_type.has_flag(.generic) { parent_sym := g.table.sym(inter_info.parent_type) diff --git a/vlib/v/gen/c/testdata/iface_method_order.c.must_have b/vlib/v/gen/c/testdata/iface_method_order.c.must_have new file mode 100644 index 0000000000..a61aeb1faf --- /dev/null +++ b/vlib/v/gen/c/testdata/iface_method_order.c.must_have @@ -0,0 +1,18 @@ +struct _main__Foo_interface_methods { +void (*_method_a)(void* _); +void (*_method_b)(void* _); +}; +struct _main__Foo_interface_methods main__Foo_name_table[3] = { +{ +._method_a = (void*) main__Bar_a_Interface_main__Foo_method_wrapper, +._method_b = (void*) main__Bar_b_Interface_main__Foo_method_wrapper, +}, +{ +._method_a = (void*) 0, +._method_b = (void*) 0, +}, +{ +._method_a = (void*) main__Baz_a_Interface_main__Foo_method_wrapper, +._method_b = (void*) main__Baz_b_Interface_main__Foo_method_wrapper, +}, +}; \ No newline at end of file diff --git a/vlib/v/gen/c/testdata/iface_method_order.vv b/vlib/v/gen/c/testdata/iface_method_order.vv new file mode 100644 index 0000000000..615d5dbee6 --- /dev/null +++ b/vlib/v/gen/c/testdata/iface_method_order.vv @@ -0,0 +1,18 @@ +interface Foo { + a() + b() +} + +struct Bar implements Foo { +} + +fn (b Bar) b() {} + +fn (b Bar) a() {} + +struct Baz implements Foo { +} + +fn (b Baz) b() {} + +fn (b Baz) a() {}