mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix possible race condition with struct offsets
This commit is contained in:
@@ -6802,7 +6802,11 @@ gb_internal void check_parsed_files(Checker *c) {
|
|||||||
for_array(i, c->info.definitions) {
|
for_array(i, c->info.definitions) {
|
||||||
Entity *e = c->info.definitions[i];
|
Entity *e = c->info.definitions[i];
|
||||||
if (e->kind == Entity_TypeName && e->type != nullptr && is_type_typed(e->type)) {
|
if (e->kind == Entity_TypeName && e->type != nullptr && is_type_typed(e->type)) {
|
||||||
|
if (e->TypeName.is_type_alias) {
|
||||||
|
// Ignore for the time being
|
||||||
|
} else {
|
||||||
(void)type_align_of(e->type);
|
(void)type_align_of(e->type);
|
||||||
|
}
|
||||||
} else if (e->kind == Entity_Procedure) {
|
} else if (e->kind == Entity_Procedure) {
|
||||||
DeclInfo *decl = e->decl_info;
|
DeclInfo *decl = e->decl_info;
|
||||||
ast_node(pl, ProcLit, decl->proc_lit);
|
ast_node(pl, ProcLit, decl->proc_lit);
|
||||||
|
|||||||
+10
-6
@@ -152,10 +152,11 @@ struct TypeStruct {
|
|||||||
|
|
||||||
bool is_polymorphic;
|
bool is_polymorphic;
|
||||||
bool are_offsets_set : 1;
|
bool are_offsets_set : 1;
|
||||||
bool are_offsets_being_processed : 1;
|
|
||||||
bool is_packed : 1;
|
bool is_packed : 1;
|
||||||
bool is_raw_union : 1;
|
bool is_raw_union : 1;
|
||||||
bool is_poly_specialized : 1;
|
bool is_poly_specialized : 1;
|
||||||
|
|
||||||
|
std::atomic<bool> are_offsets_being_processed;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeUnion {
|
struct TypeUnion {
|
||||||
@@ -4099,18 +4100,18 @@ gb_internal bool type_set_offsets(Type *t) {
|
|||||||
if (t->kind == Type_Struct) {
|
if (t->kind == Type_Struct) {
|
||||||
MUTEX_GUARD(&t->Struct.offset_mutex);
|
MUTEX_GUARD(&t->Struct.offset_mutex);
|
||||||
if (!t->Struct.are_offsets_set) {
|
if (!t->Struct.are_offsets_set) {
|
||||||
t->Struct.are_offsets_being_processed = true;
|
t->Struct.are_offsets_being_processed.store(true);
|
||||||
t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union, t->Struct.custom_min_field_align, t->Struct.custom_max_field_align);
|
t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union, t->Struct.custom_min_field_align, t->Struct.custom_max_field_align);
|
||||||
t->Struct.are_offsets_being_processed = false;
|
t->Struct.are_offsets_being_processed.store(false);
|
||||||
t->Struct.are_offsets_set = true;
|
t->Struct.are_offsets_set = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (is_type_tuple(t)) {
|
} else if (is_type_tuple(t)) {
|
||||||
MUTEX_GUARD(&t->Tuple.mutex);
|
MUTEX_GUARD(&t->Tuple.mutex);
|
||||||
if (!t->Tuple.are_offsets_set) {
|
if (!t->Tuple.are_offsets_set) {
|
||||||
t->Tuple.are_offsets_being_processed = true;
|
t->Tuple.are_offsets_being_processed.store(true);
|
||||||
t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, t->Tuple.is_packed, false, 1, 0);
|
t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, t->Tuple.is_packed, false, 1, 0);
|
||||||
t->Tuple.are_offsets_being_processed = false;
|
t->Tuple.are_offsets_being_processed.store(false);
|
||||||
t->Tuple.are_offsets_set = true;
|
t->Tuple.are_offsets_set = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4293,10 +4294,13 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
|
|||||||
if (path->failure) {
|
if (path->failure) {
|
||||||
return FAILURE_SIZE;
|
return FAILURE_SIZE;
|
||||||
}
|
}
|
||||||
if (t->Struct.are_offsets_being_processed && t->Struct.offsets == nullptr) {
|
{
|
||||||
|
MUTEX_GUARD(&t->Struct.offset_mutex);
|
||||||
|
if (t->Struct.are_offsets_being_processed.load() && t->Struct.offsets == nullptr) {
|
||||||
type_path_print_illegal_cycle(path, path->path.count-1);
|
type_path_print_illegal_cycle(path, path->path.count-1);
|
||||||
return FAILURE_SIZE;
|
return FAILURE_SIZE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
type_set_offsets(t);
|
type_set_offsets(t);
|
||||||
GB_ASSERT(t->Struct.fields.count == 0 || t->Struct.offsets != nullptr);
|
GB_ASSERT(t->Struct.fields.count == 0 || t->Struct.offsets != nullptr);
|
||||||
size = t->Struct.offsets[cast(isize)count-1] + type_size_of_internal(t->Struct.fields[cast(isize)count-1]->type, path);
|
size = t->Struct.offsets[cast(isize)count-1] + type_size_of_internal(t->Struct.fields[cast(isize)count-1]->type, path);
|
||||||
|
|||||||
Reference in New Issue
Block a user