From 0e4eea80ca3b2928a6e1a1ed5d40ac2bc5d44ccd Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Thu, 22 Jun 2023 22:39:05 +0300 Subject: [PATCH] cgen: fix code generation for generic unions (#18513) --- vlib/v/gen/c/struct.v | 6 +++++- vlib/v/tests/generics_union_dump_test.v | 28 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/generics_union_dump_test.v diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index 8cd01034f2..f037958ba1 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -393,7 +393,11 @@ fn (mut g Gen) struct_decl(s ast.Struct, name string, is_anon bool) { return } if name.contains('_T_') { - g.typedefs.writeln('typedef struct ${name} ${name};') + if s.is_union { + g.typedefs.writeln('typedef union ${name} ${name};') + } else { + g.typedefs.writeln('typedef struct ${name} ${name};') + } } // TODO avoid buffer manip start_pos := g.type_definitions.len diff --git a/vlib/v/tests/generics_union_dump_test.v b/vlib/v/tests/generics_union_dump_test.v new file mode 100644 index 0000000000..31c6471390 --- /dev/null +++ b/vlib/v/tests/generics_union_dump_test.v @@ -0,0 +1,28 @@ +union Convertor[T] { + value T + bytes [8]u8 +} + +fn test_conversion_works() { + a := Convertor[i64]{ + value: 21474837714 + } + $if little_endian { + assert unsafe { a.bytes } == [u8(210), 4, 0, 0, 5, 0, 0, 0]! + } +} + +fn test_dumping_of_a_generic_union_value() { + dump(Convertor[u8]{ + bytes: [u8(210), 4, 0, 0, 5, 0, 0, 0]! + }) + dump(Convertor[i16]{ + bytes: [u8(210), 4, 0, 0, 5, 0, 0, 0]! + }) + dump(Convertor[int]{ + bytes: [u8(210), 4, 0, 0, 5, 0, 0, 0]! + }) + dump(Convertor[i64]{ + bytes: [u8(210), 4, 0, 0, 5, 0, 0, 0]! + }) +}