checker: fix C struct embedded init fields checking (#21137)

This commit is contained in:
Felipe Pena 2024-03-31 03:11:36 -03:00 committed by GitHub
parent 5bccacae51
commit dbc4896aa1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 8 deletions

View File

@ -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
}
@ -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) {
@ -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 {
@ -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) {
@ -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 {

View File

@ -13,6 +13,12 @@ typedef struct Test1 {
/////
typedef struct MyCStruct {
char* data;
} MyCStruct;
/////
typedef struct Foo {
int a;
} Foo;

View File

@ -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
}