diff --git a/CMakeLists.txt b/CMakeLists.txt index 266ac0354b..854dc55afa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,8 +146,10 @@ if((CLANG_ASAN_UBSAN AND CLANG_MSAN) message(FATAL_ERROR "Sanitizers cannot be enabled simultaneously") endif() -if((CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang") - message(FATAL_ERROR "Sanitizers are only supported for Clang") +if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN) + if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_C_COMPILER_ID MATCHES "GNU") + message(FATAL_ERROR "Sanitizers are only supported for Clang and GCC") + endif() endif() # Place targets in bin/ or lib/ for all build configurations diff --git a/src/.asan-blacklist b/src/.asan-blacklist deleted file mode 100644 index 928d81bd5a..0000000000 --- a/src/.asan-blacklist +++ /dev/null @@ -1,3 +0,0 @@ -# multiqueue.h pointer arithmetic is not accepted by asan -fun:multiqueue_node_data -fun:tv_dict_watcher_node_data diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 9b42a442a1..b348520616 100755 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -803,8 +803,7 @@ if(CLANG_ASAN_UBSAN) -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address - -fsanitize=undefined - -fsanitize-blacklist=${PROJECT_SOURCE_DIR}/src/.asan-blacklist) + -fsanitize=undefined) target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined) elseif(CLANG_MSAN) message(STATUS "Enabling Clang memory sanitizer for nvim.") diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 4a2654f03e..84e4067f9d 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -518,13 +518,15 @@ static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q) REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET REAL_FATTR_PURE - REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; + REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE + FUNC_ATTR_NO_SANITIZE_ADDRESS; /// Compute the `DictWatcher` address from a QUEUE node. /// /// This only exists for .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer /// arithmetic). static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q) + FUNC_ATTR_NO_SANITIZE_ADDRESS { return QUEUE_DATA(q, DictWatcher, node); } diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index e05084b656..8f8a36eff9 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -245,6 +245,7 @@ static void multiqueue_push(MultiQueue *this, Event event) } static MultiQueueItem *multiqueue_node_data(QUEUE *q) + FUNC_ATTR_NO_SANITIZE_ADDRESS { return QUEUE_DATA(q, MultiQueueItem, node); } diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index 6c049df6ff..4b434f6771 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -99,6 +99,10 @@ # undef FUNC_ATTR_NO_SANITIZE_UNDEFINED #endif +#ifdef FUNC_ATTR_NO_SANITIZE_ADDRESS +# undef FUNC_ATTR_NO_SANITIZE_ADDRESS +#endif + #ifdef FUNC_ATTR_PRINTF # undef FUNC_ATTR_PRINTF #endif @@ -139,6 +143,11 @@ # define REAL_FATTR_NO_SANITIZE_UNDEFINED \ __attribute__((no_sanitize("undefined"))) # endif + +# if NVIM_HAS_ATTRIBUTE(no_sanitize_address) +# define REAL_FATTR_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize_address)) +# endif # endif // Define attributes that are not defined for this compiler. @@ -199,6 +208,10 @@ # define REAL_FATTR_NO_SANITIZE_UNDEFINED # endif +# ifndef REAL_FATTR_NO_SANITIZE_ADDRESS +# define REAL_FATTR_NO_SANITIZE_ADDRESS +# endif + # ifndef REAL_FATTR_PRINTF # define REAL_FATTR_PRINTF(x, y) # endif @@ -233,6 +246,7 @@ # define FUNC_ATTR_NONNULL_RET REAL_FATTR_NONNULL_RET # define FUNC_ATTR_NORETURN REAL_FATTR_NORETURN # define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED +# define FUNC_ATTR_NO_SANITIZE_ADDRESS REAL_FATTR_NO_SANITIZE_ADDRESS # define FUNC_ATTR_PRINTF(x, y) REAL_FATTR_PRINTF(x, y) #elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES) # define FUNC_ATTR_MALLOC @@ -249,5 +263,6 @@ # define FUNC_ATTR_NONNULL_RET # define FUNC_ATTR_NORETURN # define FUNC_ATTR_NO_SANITIZE_UNDEFINED +# define FUNC_ATTR_NO_SANITIZE_ADDRESS # define FUNC_ATTR_PRINTF(x, y) #endif diff --git a/src/uncrustify.cfg b/src/uncrustify.cfg index f9e6617d40..9c6b6bac6c 100644 --- a/src/uncrustify.cfg +++ b/src/uncrustify.cfg @@ -3504,6 +3504,7 @@ set QUESTION FUNC_ATTR_NONNULL_ARG set QUESTION FUNC_ATTR_NONNULL_RET set QUESTION FUNC_ATTR_NORETURN set QUESTION FUNC_ATTR_NO_SANITIZE_UNDEFINED +set QUESTION FUNC_ATTR_NO_SANITIZE_ADDRESS set QUESTION FUNC_ATTR_PRINTF set QUESTION FUNC_ATTR_PURE set QUESTION FUNC_ATTR_UNUSED