Skip to content

Commit af5ed53

Browse files
committed
Poison memory in variant destroy
In the version of `__destroy` that does not destruct any part of `__data`, MSAN is unable to see that `__data` is logically uninitialized. This allows false negatives such as the following to run without any MSAN diagnostic. ``` std::variant<double, int> v; v.emplace<double>(); double& d = std::get<double>(v); v.emplace<int>(); if (d) ... ``` With these changes, MSAN reports uninitialized memory: ``` ==32202==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x5557b64820aa in main /home/ccotter/variant_msan.cpp:19:9 #1 0x7fbfacd88554 in __libc_start_main /usr/src/debug/glibc-2.17-c758a686/csu/../csu/libc-start.c:266 #2 0x5557b63ed40d in _start (/home/ccotter/a.out+0x3140d) ```
1 parent b7ed097 commit af5ed53

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

libcxx/include/variant

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ namespace std {
261261
#include <new>
262262
#include <version>
263263

264+
#if __has_feature(memory_sanitizer)
265+
#include <sanitizer/msan_interface.h>
266+
#endif
267+
264268
// standard-mandated includes
265269

266270
// [variant.syn]
@@ -781,6 +785,9 @@ _LIBCPP_VARIANT_DESTRUCTOR(
781785
_Trait::_TriviallyAvailable,
782786
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__dtor() = default,
783787
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __destroy() noexcept {
788+
#if __has_feature(memory_sanitizer)
789+
__sanitizer_dtor_callback(&this->__data, sizeof(this->__data));
790+
#endif
784791
this->__index = __variant_npos<__index_t>;
785792
} _LIBCPP_EAT_SEMICOLON);
786793

0 commit comments

Comments
 (0)