diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -517,3 +517,52 @@ ``format-string`` and ``wformat-string`` became ``basic_format_string``, ``format_string``, and ``wformat_string`` in C++23. Libc++ makes these types available in C++20 as an extension. + +Turning off ASan annotation in containers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Struct template ``__asan_annotate_container_with_allocator`` may be used to turn off +`ASan annotations for containers ` with a specific allocator. +If ``__asan_annotate_container_with_allocator<_Alloc>::value == false``, container won't be poisoned at all. +Value may be changed by template specialization. Variable ``value`` is of type ``bool``. + +If you are creating allocator not working correctly with container annotations from libc++, +a better choice may be unpoisoning memory, if possible. This way, ASan benefits are present in the program. + +If one wants to turn off annotations for a simple ``user_allocator`` with one template argument, +one may do a specialization like below: + +.. code-block:: cpp + + template + struct std::__asan_annotate_container_with_allocator> { + static bool const value = false; + }; + +It is possible to turn off annotations only for buffers of a specific type (``user_type``), +allocated with ``user_allocator``. + +.. code-block:: cpp + + template <> + struct std::__asan_annotate_container_with_allocator> { + static bool const value = false; + }; + +Changing ``value`` to ``true`` will explicitly turn on annotations, when compiled with ASan. + +Why may I want to turn it off? +------------------------------ + +There are a few reasons why you may want to turn off annotations for an 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. + +What else can I do? +------------------- +If you know in which functions poisoned memory is accessed, you can +`turn off instrumentation inside a function with attribute ` +``__attribute__((no_sanitize("address")))``. Notice that those functions should not modify the container. + +If you are creating an allocator, you `can unpoison memory `. 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 @@ -23,6 +23,7 @@ #include <__utility/declval.h> #include <__utility/forward.h> #include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -401,6 +402,17 @@ : __is_cpp17_move_insertable<_Alloc> { }; +// ASan choices +template +struct __asan_annotate_container_with_allocator { +# if _LIBCPP_CLANG_VER >= 1600 + static bool const value = true; +# else + // TODO LLVM18: Remove the special-casing + static bool const value = std::is_same<_Alloc, std::allocator<_Alloc::value_type> >::value; +# endif +}; + #undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX _LIBCPP_END_NAMESPACE_STD