# define unpredictable(_x) _x
#endif
+/*
+ * GNU version check
+ */
+#ifdef __GNUC__
+#define __GNUC_PREREQ__(x, y) \
+ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
+ (__GNUC__ > (x)))
+#else
+#define __GNUC_PREREQ__(x, y) 0
+#endif
+
+
/*
* Macros to add pragmas
*/
# define CC_RELEASE_HANDLE(_tag)
#endif
+/*
+ * Disable various forms of ubsan
+ */
+#if defined(__clang__) && __has_feature(undefined_behavior_sanitizer)
+# define CC_NO_UBSAN(_sanitize) __attribute__((no_sanitize(STRINGIFY(_sanitize))))
+#elif __GNUC_PREREQ__(4, 9) && defined(__SANITIZE_UNDEFINED__)
+# define CC_NO_UBSAN(_sanitize) __attribute__((no_sanitize_undefined))
+#else
+# define CC_NO_UBSAN(_sanitize)
+#endif
+
+/*
+ * Disable sanitizers for undefined behaviour
+ */
+#if defined(__clang__)
+# define CC_NO_SANITIZE_UNDEFINED(_what) CC_HINT(no_sanitize(_what)))
+#else
+# define CC_NO_SANITIZE_UNDEFINED(_what)
+#endif
+
/*
* Macros for controlling warnings in GCC >= 4.2 and clang >= 2.8
*/
/** Call a list of watch functions associated with a state
*
*/
+CC_NO_UBSAN(function) /* UBSAN: false positive - Public/private version of connection_t trips -fsanitize=function */
static inline void connection_watch_call(connection_t *conn, fr_dlist_head_t *list)
{
/*
typedef struct {
connection_init_t init;
connection_open_t open;
- connection_shutdown_t shutdown;
+ connection_shutdown_t shutdown;
connection_failed_t failed;
connection_close_t close;
} connection_funcs_t;
* @param[in] uctx that was passed to connection_add_watch_*.
*/
typedef void(*connection_watch_t)(connection_t *conn,
- connection_state_t prev, connection_state_t state, void *uctx);
+ connection_state_t prev, connection_state_t state, void *uctx);
/** @name Add watcher functions that get called before (pre) the state callback and after (post)
* @{
* - The next attribute.
* - NULL if no more attributes.
*/
+CC_NO_UBSAN(function) /* UBSAN: false positive - Type specific dcursor pointer trips --fasanitize=function */
static inline void *dcursor_next(fr_dcursor_t *cursor, fr_dcursor_iter_t iter, void *current)
{
void *next;
*
* @hidecallergraph
*/
+CC_NO_UBSAN(function) /* UBSAN: false positive - Type specific dcursor pointer trips --fasanitize=function */
static inline void *fr_dcursor_filter_next(fr_dcursor_t *cursor, fr_dcursor_eval_t eval, void const *uctx)
{
void *item;
*
* @hidecallergraph
*/
+CC_NO_UBSAN(function) /* UBSAN: false positive - Type specific dcursor pointer trips --fasanitize=function */
static inline void *fr_dcursor_filter_head(fr_dcursor_t *cursor, fr_dcursor_eval_t eval, void const *uctx)
{
void *item;
*
* @hidecallergraph
*/
+ CC_NO_UBSAN(function) /* UBSAN: false positive - Type specific dcursor pointer trips --fasanitize=function */
static inline void *fr_dcursor_filter_current(fr_dcursor_t *cursor, fr_dcursor_eval_t eval, void const *uctx)
{
void *item;