X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Fmacros.hpp;fp=src%2Fcommon%2Fmacros.hpp;h=49f163b42fb5a6c81cc3906f9016a06fac6383a2;hb=64803277bbdbe0a943360d918298a48157d9da55;hp=d2b78200e7ebab9e7e6faffd16749f2a88082bae;hpb=60f1b42d6280b6bd386abb726dca4fd3b31d8491;p=lttng-tools.git diff --git a/src/common/macros.hpp b/src/common/macros.hpp index d2b78200e..49f163b42 100644 --- a/src/common/macros.hpp +++ b/src/common/macros.hpp @@ -9,10 +9,13 @@ #ifndef _MACROS_H #define _MACROS_H -#include +#include + #include +#include #include -#include + +#include /* * Takes a pointer x and transform it so we can use it to access members @@ -36,15 +39,111 @@ */ #define LTTNG_REF(x) ((typeof(*x) *)(x)) +#ifdef NDEBUG +/* +* Force usage of the assertion condition to prevent unused variable warnings +* when `assert()` are disabled by the `NDEBUG` definition. +*/ +# define LTTNG_ASSERT(_cond) ((void) sizeof((void) (_cond), 0)) +#else +# include +# define LTTNG_ASSERT(_cond) assert(_cond) +#endif + /* * Memory allocation zeroed */ + static inline -void *zmalloc(size_t len) +void *zmalloc_internal(size_t size) +{ + return calloc(1, size); +} + +template +struct can_malloc +{ + static constexpr bool value = std::is_trivially_constructible::value; +}; + +/* + * Malloc and zero-initialize an object of type T, asserting that T can be + * safely malloc-ed (is trivially constructible). + */ +template +T *zmalloc() +{ + static_assert (can_malloc::value, "type can be malloc'ed"); + return (T *) zmalloc_internal(sizeof(T)); +} + +/* + * Malloc and zero-initialize a buffer of size `size`, asserting that type T + * can be safely malloc-ed (is trivially constructible). + */ +template +T *zmalloc(size_t size) +{ + static_assert (can_malloc::value, "type can be malloc'ed"); + LTTNG_ASSERT(size >= sizeof(T)); + return (T *) zmalloc_internal(size); +} + +/* + * Malloc and zero-initialize an array of `nmemb` elements of type T, + * asserting that T can be safely malloc-ed (is trivially constructible). + */ +template +T *calloc(size_t nmemb) +{ + static_assert (can_malloc::value, "type can be malloc'ed"); + return (T *) zmalloc_internal(nmemb * sizeof(T)); +} + +/* + * Malloc an object of type T, asserting that T can be safely malloc-ed (is + * trivially constructible). + */ +template +T *malloc() { - return calloc(1, len); + static_assert (can_malloc::value, "type can be malloc'ed"); + return (T *) malloc(sizeof(T)); } +/* + * Malloc a buffer of size `size`, asserting that type T can be safely + * malloc-ed (is trivially constructible). + */ +template +T *malloc(size_t size) +{ + static_assert (can_malloc::value, "type can be malloc'ed"); + return (T *) malloc(size); +} + +/* + * Prevent using `free` on types that are non-POD. + * + * Declare a delete prototype of free if the parameter type is not safe to free + * (non-POD). + * + * If the parameter is a pointer to void, we can't check if what is pointed + * to is safe to free or not, as we don't know what is pointed to. Ideally, + * all calls to free would be with a typed pointer, but there are too many + * instances of passing a pointer to void to enforce that right now. So allow + * pointers to void, these will not be checked. + */ + +template +struct is_pod_or_void +{ + static constexpr bool value = std::is_pod::value || std::is_void::value; +}; + +template::value>::type> +void free(T *p) = delete; + #ifndef ARRAY_SIZE #define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) #endif @@ -130,15 +229,4 @@ int lttng_strncpy(char *dst, const char *src, size_t dst_len) return 0; } -#ifdef NDEBUG -/* -* Force usage of the assertion condition to prevent unused variable warnings -* when `assert()` are disabled by the `NDEBUG` definition. -*/ -# define LTTNG_ASSERT(_cond) ((void) sizeof((void) (_cond), 0)) -#else -# include -# define LTTNG_ASSERT(_cond) assert(_cond) -#endif - #endif /* _MACROS_H */