From 6ff1e227c884e2c903cdccfe1421f601abce1c80 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 14 Mar 2025 12:48:52 +0100 Subject: [PATCH] Cleanup: makesdna: Replace 'void' MEM_[cm]allocN with templated, type-safe MEM_[cm]allocN. The main issue of 'type-less' standard C allocations is that there is no check on allocated type possible. This is a serious source of annoyance (and crashes) when making some low-level structs non-trivial, as tracking down all usages of these structs in higher-level other structs and their allocation is... really painful. MEM_[cm]allocN templates on the other hand do check that the given type is trivial, at build time (static assert), which makes such issue... trivial to catch. NOTE: New code should strive to use MEM_new (i.e. allocation and construction) as much as possible, even for trivial PoD types. Pull Request: https://projects.blender.org/blender/blender/pulls/135971 --- source/blender/makesdna/intern/dna_genfile.cc | 47 +++++++------------ source/blender/makesdna/intern/dna_utils.cc | 3 +- source/blender/makesdna/intern/makesdna.cc | 25 ++++------ 3 files changed, 29 insertions(+), 46 deletions(-) diff --git a/source/blender/makesdna/intern/dna_genfile.cc b/source/blender/makesdna/intern/dna_genfile.cc index 668d41b7a3d..8c292e2e330 100644 --- a/source/blender/makesdna/intern/dna_genfile.cc +++ b/source/blender/makesdna/intern/dna_genfile.cc @@ -360,8 +360,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error sdna->members_num_alloc = sdna->members_num; data++; - sdna->members = static_cast( - MEM_callocN(sizeof(void *) * sdna->members_num, "sdnanames")); + sdna->members = MEM_calloc_arrayN(size_t(sdna->members_num), "sdnanames"); } else { *r_error_message = "NAME error in SDNA file"; @@ -400,8 +399,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error } data++; - sdna->types = static_cast( - MEM_callocN(sizeof(void *) * sdna->types_num, "sdnatypes")); + sdna->types = MEM_calloc_arrayN(size_t(sdna->types_num), "sdnatypes"); } else { *r_error_message = "TYPE error in SDNA file"; @@ -454,8 +452,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error } data++; - sdna->structs = static_cast( - MEM_callocN(sizeof(SDNA_Struct *) * sdna->structs_num, "sdnastrcs")); + sdna->structs = MEM_calloc_arrayN(size_t(sdna->structs_num), "sdnastrcs"); } else { *r_error_message = "STRC error in SDNA file"; @@ -534,16 +531,14 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error /* Cache name size. */ { - short *members_array_num = static_cast( - MEM_mallocN(sizeof(*members_array_num) * sdna->members_num, __func__)); + short *members_array_num = MEM_malloc_arrayN(size_t(sdna->members_num), __func__); for (int member_index = 0; member_index < sdna->members_num; member_index++) { members_array_num[member_index] = DNA_member_array_num(sdna->members[member_index]); } sdna->members_array_num = members_array_num; } - sdna->types_alignment = static_cast( - MEM_malloc_arrayN(sdna->types_num, sizeof(int), __func__)); + sdna->types_alignment = MEM_malloc_arrayN(size_t(sdna->types_num), __func__); for (int type_index = 0; type_index < sdna->types_num; type_index++) { sdna->types_alignment[type_index] = int(__STDCPP_DEFAULT_NEW_ALIGNMENT__); } @@ -570,12 +565,12 @@ SDNA *DNA_sdna_from_data(const void *data, const bool do_alias, const char **r_error_message) { - SDNA *sdna = static_cast(MEM_mallocN(sizeof(*sdna), "sdna")); + SDNA *sdna = MEM_mallocN("sdna"); const char *error_message = nullptr; sdna->data_size = data_len; if (data_alloc) { - char *data_copy = static_cast(MEM_mallocN(data_len, "sdna_data")); + char *data_copy = MEM_malloc_arrayN(size_t(data_len), "sdna_data"); memcpy(data_copy, data, data_len); sdna->data = data_copy; } @@ -719,7 +714,7 @@ const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna return nullptr; } - char *compare_flags = static_cast(MEM_mallocN(oldsdna->structs_num, "compare flags")); + char *compare_flags = MEM_malloc_arrayN(size_t(oldsdna->structs_num), "compare flags"); memset(compare_flags, SDNA_CMP_UNKNOWN, oldsdna->structs_num); /* Set correct flag for every struct. */ @@ -1561,8 +1556,8 @@ static ReconstructStep *create_reconstruct_steps_for_struct(const SDNA *oldsdna, const SDNA_Struct *old_struct, const SDNA_Struct *new_struct) { - ReconstructStep *steps = static_cast( - MEM_calloc_arrayN(new_struct->members_num, sizeof(ReconstructStep), __func__)); + ReconstructStep *steps = MEM_calloc_arrayN(size_t(new_struct->members_num), + __func__); int new_member_offset = 0; for (int new_member_index = 0; new_member_index < new_struct->members_num; new_member_index++) { @@ -1627,15 +1622,13 @@ DNA_ReconstructInfo *DNA_reconstruct_info_create(const SDNA *oldsdna, const SDNA *newsdna, const char *compare_flags) { - DNA_ReconstructInfo *reconstruct_info = static_cast( - MEM_callocN(sizeof(DNA_ReconstructInfo), __func__)); + DNA_ReconstructInfo *reconstruct_info = MEM_callocN(__func__); reconstruct_info->oldsdna = oldsdna; reconstruct_info->newsdna = newsdna; reconstruct_info->compare_flags = compare_flags; - reconstruct_info->step_counts = static_cast( - MEM_malloc_arrayN(newsdna->structs_num, sizeof(int), __func__)); - reconstruct_info->steps = static_cast( - MEM_malloc_arrayN(newsdna->structs_num, sizeof(ReconstructStep *), __func__)); + reconstruct_info->step_counts = MEM_malloc_arrayN(size_t(newsdna->structs_num), __func__); + reconstruct_info->steps = MEM_malloc_arrayN(size_t(newsdna->structs_num), + __func__); /* Generate reconstruct steps for all structs. */ for (int new_struct_index = 0; new_struct_index < newsdna->structs_num; new_struct_index++) { @@ -1904,10 +1897,8 @@ static void sdna_expand_names(SDNA *sdna) const SDNA_Struct *struct_old = sdna->structs[struct_index]; names_expand_len += struct_old->members_num; } - const char **names_expand = static_cast( - MEM_mallocN(sizeof(*names_expand) * names_expand_len, __func__)); - short *names_array_len_expand = static_cast( - MEM_mallocN(sizeof(*names_array_len_expand) * names_expand_len, __func__)); + const char **names_expand = MEM_malloc_arrayN(size_t(names_expand_len), __func__); + short *names_array_len_expand = MEM_malloc_arrayN(size_t(names_expand_len), __func__); int names_expand_index = 0; for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) { @@ -1986,8 +1977,7 @@ void DNA_sdna_alias_data_ensure(SDNA *sdna) DNA_RENAME_ALIAS_FROM_STATIC, &type_map_alias_from_static, &member_map_alias_from_static); if (sdna->alias.types == nullptr) { - sdna->alias.types = static_cast( - MEM_mallocN(sizeof(*sdna->alias.types) * sdna->types_num, __func__)); + sdna->alias.types = MEM_malloc_arrayN(size_t(sdna->types_num), __func__); for (int type_index = 0; type_index < sdna->types_num; type_index++) { const char *type_name_static = sdna->types[type_index]; @@ -2002,8 +1992,7 @@ void DNA_sdna_alias_data_ensure(SDNA *sdna) if (sdna->alias.members == nullptr) { sdna_expand_names(sdna); - sdna->alias.members = static_cast( - MEM_mallocN(sizeof(*sdna->alias.members) * sdna->members_num, __func__)); + sdna->alias.members = MEM_malloc_arrayN(size_t(sdna->members_num), __func__); for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) { const SDNA_Struct *struct_info = sdna->structs[struct_index]; const char *struct_name_static = sdna->types[struct_info->type_index]; diff --git a/source/blender/makesdna/intern/dna_utils.cc b/source/blender/makesdna/intern/dna_utils.cc index 41c0479d24a..5b8ce20c476 100644 --- a/source/blender/makesdna/intern/dna_utils.cc +++ b/source/blender/makesdna/intern/dna_utils.cc @@ -260,8 +260,7 @@ void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_type_map, GHash * GHash *member_map = BLI_ghash_new_ex( strhash_pair_p, strhash_pair_cmp, __func__, ARRAY_SIZE(member_data)); for (int i = 0; i < ARRAY_SIZE(member_data); i++) { - const char **str_pair = static_cast( - MEM_mallocN(sizeof(char *) * 2, __func__)); + const char **str_pair = MEM_malloc_arrayN(2, __func__); str_pair[0] = static_cast( BLI_ghash_lookup_default(type_map_local, member_data[i][0], (void *)member_data[i][0])); str_pair[1] = member_data[i][elem_key]; diff --git a/source/blender/makesdna/intern/makesdna.cc b/source/blender/makesdna/intern/makesdna.cc index 5131ee448cc..1344ab19c41 100644 --- a/source/blender/makesdna/intern/makesdna.cc +++ b/source/blender/makesdna/intern/makesdna.cc @@ -567,7 +567,7 @@ static int preprocess_include(char *maindata, const int maindata_len) { /* NOTE: len + 1, last character is a dummy to prevent * comparisons using uninitialized memory */ - char *temp = static_cast(MEM_mallocN(maindata_len + 1, "preprocess_include")); + char *temp = MEM_malloc_arrayN(size_t(maindata_len) + 1, "preprocess_include"); temp[maindata_len] = ' '; memcpy(temp, maindata, maindata_len); @@ -1275,23 +1275,18 @@ static int make_structDNA(const char *base_directory, mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); /* the longest known struct is 50k, so we assume 100k is sufficient! */ - structdata = static_cast(MEM_callocN(max_data_size, "structdata")); + structdata = MEM_calloc_arrayN(size_t(max_data_size), "structdata"); /* a maximum of 5000 variables, must be sufficient? */ - members = static_cast(MEM_callocN(sizeof(char *) * max_array_len, "names")); - types = static_cast(MEM_callocN(sizeof(char *) * max_array_len, "types")); - types_size_native = static_cast( - MEM_callocN(sizeof(short) * max_array_len, "types_size_native")); - types_size_32 = static_cast( - MEM_callocN(sizeof(short) * max_array_len, "types_size_32")); - types_size_64 = static_cast( - MEM_callocN(sizeof(short) * max_array_len, "types_size_64")); - types_align_32 = static_cast( - MEM_callocN(sizeof(short) * max_array_len, "types_size_32")); - types_align_64 = static_cast( - MEM_callocN(sizeof(short) * max_array_len, "types_size_64")); + members = MEM_calloc_arrayN(size_t(max_array_len), "names"); + types = MEM_calloc_arrayN(size_t(max_array_len), "types"); + types_size_native = MEM_calloc_arrayN(size_t(max_array_len), "types_size_native"); + types_size_32 = MEM_calloc_arrayN(size_t(max_array_len), "types_size_32"); + types_size_64 = MEM_calloc_arrayN(size_t(max_array_len), "types_size_64"); + types_align_32 = MEM_calloc_arrayN(size_t(max_array_len), "types_size_32"); + types_align_64 = MEM_calloc_arrayN(size_t(max_array_len), "types_size_64"); - structs = static_cast(MEM_callocN(sizeof(short *) * max_array_len, "structs")); + structs = MEM_calloc_arrayN(size_t(max_array_len), "structs"); /* Build versioning data */ DNA_alias_maps(DNA_RENAME_ALIAS_FROM_STATIC,