libobs/util: Add type test in darray macros for GCC

Previously darray macros did not test the types of arguments so that
developers cannot notice even if a wrong type of a variable is passed.
This commit add a type test that relys on GCC's extension. Since OBS
Studio is built with GCC for Ubuntu, testing only under GCC is
sufficient to catch future bugs.
master
Norihiro Kamae 2021-10-01 12:35:59 +09:00
parent ef5e04a621
commit 93ee7c4775
2 changed files with 101 additions and 1 deletions

View File

@ -207,6 +207,11 @@ if(APPLE)
elseif(UNIX)
option(USE_XDG "Utilize XDG Base Directory Specification" ON)
option(ENABLE_WAYLAND "Build support for Wayland" ON)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
option(ENABLE_DARRAY_TYPE_TEST "Test types of darray argument" ON)
else()
option(ENABLE_DARRAY_TYPE_TEST "Test types of darray argument" OFF)
endif()
if(USE_XDG)
add_definitions(-DUSE_XDG)
@ -215,6 +220,10 @@ elseif(UNIX)
if(NOT UNIX_STRUCTURE)
list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN")
endif()
if(ENABLE_DARRAY_TYPE_TEST)
add_definitions(-DENABLE_DARRAY_TYPE_TEST)
endif()
endif()
if(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "e2k")

View File

@ -494,33 +494,124 @@ static inline void darray_swap(const size_t element_size, struct darray *dst,
#define da_move(dst, src) darray_move(&dst.da, &src.da)
#define da_find(v, item, idx) darray_find(sizeof(*v.array), &v.da, item, idx)
#ifdef ENABLE_DARRAY_TYPE_TEST
#ifdef __cplusplus
#define da_type_test(v, item) \
({ \
if (false) { \
auto _t = v.array; \
_t = (item); \
(void)_t; \
*(v).array = *(item); \
} \
})
#else
#define da_type_test(v, item) \
({ \
if (false) { \
const typeof(*v.array) *_t; \
_t = (item); \
(void)_t; \
*(v).array = *(item); \
} \
})
#endif
#endif // ENABLE_DARRAY_TYPE_TEST
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_find(v, item, idx) \
({ \
da_type_test(v, item); \
darray_find(sizeof(*v.array), &v.da, item, idx); \
})
#else
#define da_find(v, item, idx) darray_find(sizeof(*v.array), &v.da, item, idx)
#endif
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_push_back(v, item) \
({ \
da_type_test(v, item); \
darray_push_back(sizeof(*v.array), &v.da, item); \
})
#else
#define da_push_back(v, item) darray_push_back(sizeof(*v.array), &v.da, item)
#endif
#define da_push_back_new(v) darray_push_back_new(sizeof(*v.array), &v.da)
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_push_back_array(dst, src_array, n) \
({ \
da_type_test(dst, src_array); \
darray_push_back_array(sizeof(*dst.array), &dst.da, src_array, \
n); \
})
#else
#define da_push_back_array(dst, src_array, n) \
darray_push_back_array(sizeof(*dst.array), &dst.da, src_array, n)
#endif
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_push_back_da(dst, src) \
({ \
da_type_test(dst, src.array); \
darray_push_back_darray(sizeof(*dst.array), &dst.da, &src.da); \
})
#else
#define da_push_back_da(dst, src) \
darray_push_back_darray(sizeof(*dst.array), &dst.da, &src.da)
#endif
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_insert(v, idx, item) \
({ \
da_type_test(v, item); \
darray_insert(sizeof(*v.array), &v.da, idx, item); \
})
#else
#define da_insert(v, idx, item) \
darray_insert(sizeof(*v.array), &v.da, idx, item)
#endif
#define da_insert_new(v, idx) darray_insert_new(sizeof(*v.array), &v.da, idx)
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_insert_array(dst, idx, src_array, n) \
({ \
da_type_test(dst, src_array); \
darray_insert_array(sizeof(*dst.array), &dst.da, idx, \
src_array, n); \
})
#else
#define da_insert_array(dst, idx, src_array, n) \
darray_insert_array(sizeof(*dst.array), &dst.da, idx, src_array, n)
#endif
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_insert_da(dst, idx, src) \
({ \
da_type_test(dst, src.array); \
darray_insert_darray(sizeof(*dst.array), &dst.da, idx, \
&src.da); \
})
#else
#define da_insert_da(dst, idx, src) \
darray_insert_darray(sizeof(*dst.array), &dst.da, idx, &src.da)
#endif
#define da_erase(dst, idx) darray_erase(sizeof(*dst.array), &dst.da, idx)
#ifdef ENABLE_DARRAY_TYPE_TEST
#define da_erase_item(dst, item) \
({ \
da_type_test(dst, item); \
darray_erase_item(sizeof(*dst.array), &dst.da, item); \
})
#else
#define da_erase_item(dst, item) \
darray_erase_item(sizeof(*dst.array), &dst.da, item)
#endif
#define da_erase_range(dst, from, to) \
darray_erase_range(sizeof(*dst.array), &dst.da, from, to)