diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -523,3 +523,32 @@ versions. This allows the library to have better estimates for newly introduced Unicode code points, without requiring the user to use the latest C++ version in their code base. +======= +Turning off ASan annotation in containers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``__asan_annotate_container_with_allocator`` is a customization point to allow users to disable +`Address Sanitizer annotations for containers `_ for specific allocators. This may be necessary for allocators that access allocated memory. +This customization point exists only when ``_LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS`` Feature Test Macro is defined. + +For allocators not running destructors, it is also possible to `bulk-unpoison memory `_ instead of disabling annotations altogether. + +The struct may be specialized for user-defined allocators. It is a `Cpp17UnaryTypeTrait `_ with a base characteristic of ``true_type`` if the container is allowed to use annotations and ``false_type`` otherwise. + +The annotations for a ``user_allocator`` can be disabled like this: + +.. code-block:: cpp + + #ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS + template + struct std::__asan_annotate_container_with_allocator> : std::false_type {}; + #endif + +Why may I want to turn it off? +------------------------------ + +There are a few reasons why you may want to turn off annotations for an allocator. +Unpoisoning may not be an option, if (for example) you are not maintaining the allocator. + +* You are using allocator, which does not call destructor during deallocation. +* You are aware that memory allocated with an allocator may be accessed, even when unused by container. diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h --- a/libcxx/include/__memory/allocator_traits.h +++ b/libcxx/include/__memory/allocator_traits.h @@ -401,6 +401,25 @@ : __is_cpp17_move_insertable<_Alloc> { }; +// ASan choices +#ifndef _LIBCPP_HAS_NO_ASAN +# define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1 +#endif + +#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS +template +struct __asan_annotate_container_with_allocator +# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1600 + : true_type {}; +# else + // TODO LLVM18: Remove the special-casing + : false_type {}; +# endif + +template +struct __asan_annotate_container_with_allocator > : true_type {}; +#endif + #undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX _LIBCPP_END_NAMESPACE_STD