Skip to content

Commit

Permalink
checker: fix C struct embedded init fields checking (#21137)
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Mar 31, 2024
1 parent 5bccaca commit dbc4896
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
13 changes: 5 additions & 8 deletions vlib/v/checker/struct.v
Expand Up @@ -751,8 +751,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
continue
}
sym := c.table.sym(field.typ)
if field.name.len > 0 && field.name[0].is_capital() && sym.info is ast.Struct
&& sym.language == .v {
if field.name.len > 0 && field.name[0].is_capital() && sym.info is ast.Struct {
// struct embeds
continue
}
Expand Down Expand Up @@ -894,8 +893,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',

// Recursively check whether the struct type field is initialized
fn (mut c Checker) check_ref_fields_initialized(struct_sym &ast.TypeSymbol, mut checked_types []ast.Type, linked_name string, pos &token.Pos) {
if (c.pref.translated || c.file.is_translated) || (struct_sym.language == .c
&& struct_sym.info is ast.Struct && struct_sym.info.is_typedef) {
if (c.pref.translated || c.file.is_translated) || struct_sym.language == .c {
return
}
for field in c.table.struct_fields(struct_sym) {
Expand All @@ -910,7 +908,7 @@ fn (mut c Checker) check_ref_fields_initialized(struct_sym &ast.TypeSymbol, mut
}
sym := c.table.sym(field.typ)
if sym.info is ast.Struct {
if sym.language == .c && sym.info.is_typedef {
if sym.language == .c {
continue
}
if field.name.len > 0 && field.name[0].is_capital() && sym.language == .v {
Expand All @@ -937,8 +935,7 @@ fn (mut c Checker) check_ref_fields_initialized(struct_sym &ast.TypeSymbol, mut
// The goal is to give only a notice, not an error, for now. After a while,
// when we change the notice to error, we can remove this temporary method.
fn (mut c Checker) check_ref_fields_initialized_note(struct_sym &ast.TypeSymbol, mut checked_types []ast.Type, linked_name string, pos &token.Pos) {
if (c.pref.translated || c.file.is_translated) || (struct_sym.language == .c
&& struct_sym.info is ast.Struct && struct_sym.info.is_typedef) {
if (c.pref.translated || c.file.is_translated) || struct_sym.language == .c {
return
}
for field in c.table.struct_fields(struct_sym) {
Expand All @@ -953,7 +950,7 @@ fn (mut c Checker) check_ref_fields_initialized_note(struct_sym &ast.TypeSymbol,
}
sym := c.table.sym(field.typ)
if sym.info is ast.Struct {
if sym.language == .c && sym.info.is_typedef {
if sym.language == .c {
continue
}
if field.name.len > 0 && field.name[0].is_capital() && sym.language == .v {
Expand Down
6 changes: 6 additions & 0 deletions vlib/v/tests/c_structs/cstruct.h
Expand Up @@ -13,6 +13,12 @@ typedef struct Test1 {

/////

typedef struct MyCStruct {
char* data;
} MyCStruct;

/////

typedef struct Foo {
int a;
} Foo;
Expand Down
22 changes: 22 additions & 0 deletions vlib/v/tests/c_structs/cstruct_ref_test.v
@@ -0,0 +1,22 @@
#include "@VMODROOT/cstruct.h"

struct C.MyCStruct {
data &u8
}

struct MyWrapper {
C.MyCStruct
}

fn (it C.MyCStruct) wrap() MyWrapper {
return MyWrapper{
data: it.data
}
}

fn test_main() {
dump(C.MyCStruct{
data: 123
}.wrap())
assert true
}

0 comments on commit dbc4896

Please sign in to comment.