diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference --- a/libcxx/include/__bit_reference +++ b/libcxx/include/__bit_reference @@ -14,6 +14,10 @@ #include <__bits> #include +#ifdef DATAFLOW_SANITIZER +#include +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -36,9 +40,15 @@ template ::value> class __bit_reference { +#ifdef DATAFLOW_SANITIZER + typedef typename _Cp::__dfsan_labels_iterator __dfsan_label_iterator; +#endif typedef typename _Cp::__storage_type __storage_type; typedef typename _Cp::__storage_pointer __storage_pointer; - + +#ifdef DATAFLOW_SANITIZER + __dfsan_label_iterator __label_; +#endif __storage_pointer __seg_; __storage_type __mask_; @@ -51,7 +61,15 @@ __bit_reference(const __bit_reference&) = default; _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT - {return static_cast(*__seg_ & __mask_);} + { +#ifdef DATAFLOW_SANITIZER + bool __r = static_cast(*__seg_ & __mask_); + dfsan_set_label(*__label_, &__r, sizeof(__r)); + return __r; +#else + return static_cast(*__seg_ & __mask_); +#endif + } _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT {return !static_cast(*this);} @@ -62,6 +80,9 @@ *__seg_ |= __mask_; else *__seg_ &= ~__mask_; +#ifdef DATAFLOW_SANITIZER + *__label_ = dfsan_union(*__label_, dfsan_get_label(__x)); +#endif return *this; } @@ -71,11 +92,25 @@ _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {*__seg_ ^= __mask_;} _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, false> operator&() const _NOEXCEPT - {return __bit_iterator<_Cp, false>(__seg_, static_cast(__libcpp_ctz(__mask_)));} + { + return __bit_iterator<_Cp, false>( +#ifdef DATAFLOW_SANITIZER + __label_, +#endif + __seg_, static_cast(__libcpp_ctz(__mask_))); + } private: _LIBCPP_INLINE_VISIBILITY - __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT - : __seg_(__s), __mask_(__m) {} + __bit_reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_label_iterator __label, +#endif + __storage_pointer __s, __storage_type __m) _NOEXCEPT + : +#ifdef DATAFLOW_SANITIZER + __label_(__label), +#endif + __seg_(__s), __mask_(__m) {} }; template @@ -126,9 +161,15 @@ template class __bit_const_reference { +#ifdef DATAFLOW_SANITIZER + typedef typename _Cp::__dfsan_labels_iterator __dfsan_label_iterator; +#endif typedef typename _Cp::__storage_type __storage_type; typedef typename _Cp::__const_storage_pointer __storage_pointer; +#ifdef DATAFLOW_SANITIZER + __dfsan_label_iterator __label_; +#endif __storage_pointer __seg_; __storage_type __mask_; @@ -140,18 +181,44 @@ _LIBCPP_INLINE_VISIBILITY __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT - : __seg_(__x.__seg_), __mask_(__x.__mask_) {} + : +#ifdef DATAFLOW_SANITIZER + __label_(__x.__label_), +#endif + __seg_(__x.__seg_), __mask_(__x.__mask_) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT - {return static_cast(*__seg_ & __mask_);} + { +#ifdef DATAFLOW_SANITIZER + bool __r = static_cast(*__seg_ & __mask_); + dfsan_set_label(*__label_, &__r, sizeof(__r)); + return __r; +#else + return static_cast(*__seg_ & __mask_); +#endif + } _LIBCPP_INLINE_VISIBILITY __bit_iterator<_Cp, true> operator&() const _NOEXCEPT - {return __bit_iterator<_Cp, true>(__seg_, static_cast(__libcpp_ctz(__mask_)));} + { + return __bit_iterator<_Cp, true>( +#ifdef DATAFLOW_SANITIZER + __label_, +#endif + __seg_, static_cast(__libcpp_ctz(__mask_))); + } private: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT - : __seg_(__s), __mask_(__m) {} + __bit_const_reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_label_iterator __label, +#endif + __storage_pointer __s, __storage_type __m) _NOEXCEPT + : +#ifdef DATAFLOW_SANITIZER + __label_(__label), +#endif + __seg_(__s), __mask_(__m) {} __bit_const_reference& operator=(const __bit_const_reference&) = delete; }; @@ -173,25 +240,52 @@ __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); __storage_type __b = *__first.__seg_ & __m; if (__b) +#ifdef DATAFLOW_SANITIZER + return __first + _VSTD::__libcpp_ctz(__b) - __first.__ctz_; +#else return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); +#endif if (__n == __dn) return __first + __n; __n -= __dn; ++__first.__seg_; +#ifdef DATAFLOW_SANITIZER + __first.__label_ += __dn; +#endif } // do middle whole words - for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word +#ifdef DATAFLOW_SANITIZER + , __first.__label_ += __bits_per_word +#endif + ) if (*__first.__seg_) +#ifdef DATAFLOW_SANITIZER + { + int __ctz = _VSTD::__libcpp_ctz(*__first.__seg_); + return _It(__first.__label_ += __ctz, __first.__seg_, static_cast(__ctz)); + } +#else return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(*__first.__seg_))); +#endif + // do last partial word if (__n > 0) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); __storage_type __b = *__first.__seg_ & __m; if (__b) +#ifdef DATAFLOW_SANITIZER + return __first + _VSTD::__libcpp_ctz(__b); +#else return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); +#endif } - return _It(__first.__seg_, static_cast(__n)); + return _It( +#ifdef DATAFLOW_SANITIZER + __first.__label_, +#endif + __first.__seg_, static_cast(__n)); } template @@ -209,18 +303,36 @@ __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); __storage_type __b = ~*__first.__seg_ & __m; if (__b) +#ifdef DATAFLOW_SANITIZER + return __first + _VSTD::__libcpp_ctz(__b) - __first.__ctz_; +#else return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); +#endif if (__n == __dn) return __first + __n; __n -= __dn; ++__first.__seg_; +#ifdef DATAFLOW_SANITIZER + __first.__label_ += __dn; +#endif } // do middle whole words - for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word +#ifdef DATAFLOW_SANITIZER + , __first.__label_ += __bits_per_word +#endif + ) { __storage_type __b = ~*__first.__seg_; if (__b) +#ifdef DATAFLOW_SANITIZER + { + int __ctz = _VSTD::__libcpp_ctz(__b); + return _It(__first.__label_ += __ctz, __first.__seg_, static_cast(__ctz)); + } +#else return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); +#endif } // do last partial word if (__n > 0) @@ -228,9 +340,17 @@ __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); __storage_type __b = ~*__first.__seg_ & __m; if (__b) +#ifdef DATAFLOW_SANITIZER + return __first + _VSTD::__libcpp_ctz(__b); +#else return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); +#endif } - return _It(__first.__seg_, static_cast(__n)); + return _It( +#ifdef DATAFLOW_SANITIZER + __first.__label_, +#endif + __first.__seg_, static_cast(__n)); } template @@ -245,6 +365,19 @@ // count +#ifdef DATAFLOW_SANITIZER +template +dfsan_label __union_labels(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { + dfsan_label __dfsan_label = 0; + typename _Cp::size_type __i = 0; + typedef __bit_iterator<_Cp, _IsConst> _It; + for (typename _It::__dfsan_labels_iterator __it = __first.__label_; __i < __n; ++__i, ++__it) { + __dfsan_label = dfsan_union(__dfsan_label, *__it); + } + return __dfsan_label; +} +#endif + template typename __bit_iterator<_Cp, _IsConst>::difference_type __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) @@ -254,6 +387,10 @@ typedef typename _It::difference_type difference_type; const int __bits_per_word = _It::__bits_per_word; difference_type __r = 0; +#ifdef DATAFLOW_SANITIZER + dfsan_label __dfsan_label = __union_labels(__first, __n); + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); +#endif // do first partial word if (__first.__ctz_ != 0) { @@ -285,6 +422,10 @@ typedef typename _It::difference_type difference_type; const int __bits_per_word = _It::__bits_per_word; difference_type __r = 0; +#ifdef DATAFLOW_SANITIZER + dfsan_label __dfsan_label = __union_labels(__first, __n); + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); +#endif // do first partial word if (__first.__ctz_ != 0) { @@ -390,6 +531,9 @@ _VSTD::__fill_n_true(__first, __n); else _VSTD::__fill_n_false(__first, __n); +#ifdef DATAFLOW_SANITIZER + _VSTD::fill_n(__first.__label_, __n, dfsan_get_label(__value_)); +#endif } } @@ -401,6 +545,9 @@ fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value_) { _VSTD::fill_n(__first, static_cast(__last - __first), __value_); +#ifdef DATAFLOW_SANITIZER + _VSTD::fill_n(__first.__label_, __last.__label_, dfsan_get_label(__value_)); +#endif } // copy @@ -537,6 +684,9 @@ __bit_iterator<_Cp, false> copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { +#ifdef DATAFLOW_SANITIZER + __result.__label_ = _VSTD::copy(__first.__label_, __last.__label_, __result.__label_); +#endif if (__first.__ctz_ == __result.__ctz_) return _VSTD::__copy_aligned(__first, __last, __result); return _VSTD::__copy_unaligned(__first, __last, __result); @@ -684,6 +834,9 @@ __bit_iterator<_Cp, false> copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { +#ifdef DATAFLOW_SANITIZER + __result.__label_ = _VSTD::copy_backward(__first.__label_, __last.__label_, __result.__label_); +#endif if (__last.__ctz_ == __result.__ctz_) return _VSTD::__copy_backward_aligned(__first, __last, __result); return _VSTD::__copy_backward_unaligned(__first, __last, __result); @@ -867,6 +1020,9 @@ swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, __bit_iterator<__C2, false> __first2) { +#ifdef DATAFLOW_SANITIZER + __first2.__label_ = _VSTD::swap_ranges(__first1.__label_, __last1.__label_, __first2.__label_); +#endif if (__first1.__ctz_ == __first2.__ctz_) return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2); return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2); @@ -1082,9 +1238,20 @@ bool equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { +#ifdef DATAFLOW_SANITIZER + typename __bit_iterator<_Cp, _IC1>::difference_type __n = __last1 - __first1; + dfsan_label __dfsan_label = __union_labels(__first1, __n); + __dfsan_label = dfsan_union(__dfsan_label, __union_labels(__first2, __n)); + bool __r = __first1.__ctz_ == __first2.__ctz_? + _VSTD::__equal_aligned(__first1, __last1, __first2): + _VSTD::__equal_unaligned(__first1, __last1, __first2); + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else if (__first1.__ctz_ == __first2.__ctz_) return _VSTD::__equal_aligned(__first1, __last1, __first2); return _VSTD::__equal_unaligned(__first1, __last1, __first2); +#endif } template ::type __storage_pointer; static const unsigned __bits_per_word = _Cp::__bits_per_word; + +#ifdef DATAFLOW_SANITIZER + typedef typename _Cp::__dfsan_labels_iterator __dfsan_labels_iterator; +#endif +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_iterator __label_; +#endif __storage_pointer __seg_; unsigned __ctz_; @@ -1120,7 +1294,11 @@ _LIBCPP_INLINE_VISIBILITY __bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT - : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + : +#ifdef DATAFLOW_SANITIZER + __label_(__it.__label_), +#endif + __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} // The non-const __bit_iterator has historically had a non-trivial // copy constructor (as a quirk of its construction). We need to maintain @@ -1130,7 +1308,11 @@ _LIBCPP_INLINE_VISIBILITY __bit_iterator(__type_for_abi_non_trivial_copy_ctor const& __it) _NOEXCEPT - : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + : +#ifdef DATAFLOW_SANITIZER + __label_(__it.__label_), +#endif + __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} // Always declare the copy assignment operator since the implicit declaration // is deprecated. @@ -1138,7 +1320,11 @@ __bit_iterator& operator=(__bit_iterator const&) = default; _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT - {return reference(__seg_, __storage_type(1) << __ctz_);} + {return reference( +#ifdef DATAFLOW_SANITIZER + __label_, +#endif + __seg_, __storage_type(1) << __ctz_);} _LIBCPP_INLINE_VISIBILITY __bit_iterator& operator++() { @@ -1149,6 +1335,9 @@ __ctz_ = 0; ++__seg_; } +#ifdef DATAFLOW_SANITIZER + ++__label_; +#endif return *this; } @@ -1168,6 +1357,9 @@ __ctz_ = __bits_per_word - 1; --__seg_; } +#ifdef DATAFLOW_SANITIZER + --__label_; +#endif return *this; } @@ -1187,6 +1379,9 @@ / static_cast(__bits_per_word); __n &= (__bits_per_word - 1); __ctz_ = static_cast((__n + __ctz_) % __bits_per_word); +#ifdef DATAFLOW_SANITIZER + __label_ += __n; +#endif return *this; } @@ -1238,8 +1433,15 @@ private: _LIBCPP_INLINE_VISIBILITY - __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT - : __seg_(__s), __ctz_(__ctz) {} + __bit_iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_iterator __label, +#endif + __storage_pointer __s, unsigned __ctz) _NOEXCEPT +#ifdef DATAFLOW_SANITIZER + : __label_(__label), +#endif + __seg_(__s), __ctz_(__ctz) {} friend typename _Cp::__self; @@ -1296,6 +1498,11 @@ __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); template friend typename __bit_iterator<_Dp, _IC>::difference_type __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + +#ifdef DATAFLOW_SANITIZER + template friend dfsan_label + __union_labels(__bit_iterator<_Dp, _IC> __first, typename _Dp::size_type __n); +#endif }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/bitset b/libcxx/include/bitset --- a/libcxx/include/bitset +++ b/libcxx/include/bitset @@ -121,6 +121,10 @@ #include #include <__functional_base> +#ifdef DATAFLOW_SANITIZER +#include +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -151,6 +155,11 @@ typedef __bitset __self; typedef __storage_type* __storage_pointer; typedef const __storage_type* __const_storage_pointer; + +#ifdef DATAFLOW_SANITIZER + typedef vector::iterator __dfsan_labels_iterator; +#endif + static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); friend class __bit_reference<__bitset>; @@ -159,6 +168,10 @@ friend class __bit_iterator<__bitset, true>; friend struct __bit_array<__bitset>; +#ifdef DATAFLOW_SANITIZER + vector __dfsan_labels_; +#endif + __storage_type __first_[_N_words]; typedef __bit_reference<__bitset> reference; @@ -172,13 +185,29 @@ explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT - {return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + {return reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT - {return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + {return const_reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT - {return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + {return iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __first_ + __pos / __bits_per_word, __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT - {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + {return const_iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __first_ + __pos / __bits_per_word, __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset& __v) _NOEXCEPT; @@ -212,6 +241,10 @@ _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong(true_type, false_type) const; unsigned long long to_ullong(true_type, true_type) const; +#ifdef DATAFLOW_SANITIZER + dfsan_label union_labels() const _NOEXCEPT; + void merge_labels(const __bitset& __v) _NOEXCEPT; +#endif }; template @@ -221,6 +254,9 @@ #ifndef _LIBCPP_CXX03_LANG : __first_{0} #endif +#ifdef DATAFLOW_SANITIZER + , __dfsan_labels_(_Size, 0) +#endif { #ifdef _LIBCPP_CXX03_LANG _VSTD::fill_n(__first_, _N_words, __storage_type(0)); @@ -244,6 +280,9 @@ _VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_); _VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0)); +#ifdef DATAFLOW_SANITIZER + _VSTD::fill(__dfsan_labels_, _Size, dfsan_get_label(__v)); +#endif } template @@ -251,6 +290,10 @@ void __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT { +#ifdef DATAFLOW_SANITIZER + _VSTD::fill(__dfsan_labels_, _Size, dfsan_get_label(__v)); +#endif + __first_[0] = __v; if (_Size < __bits_per_word) __first_[0] &= ( 1ULL << _Size ) - 1; @@ -275,12 +318,26 @@ #error This constructor has not been ported to this platform #endif #endif +#ifdef DATAFLOW_SANITIZER + , __dfsan_labels_(_Size, 0) +#endif { #ifdef _LIBCPP_CXX03_LANG __init(__v, integral_constant()); #endif } +#ifdef DATAFLOW_SANITIZER +template +inline +void +__bitset<_N_words, _Size>::merge_labels(const __bitset& __v) _NOEXCEPT +{ + for (size_type __i = 0; __i < _Size; ++__i) + __dfsan_labels_[__i] = dfsan_union(__dfsan_labels_[__i], __v.__dfsan_labels_[__i]); +} +#endif + template inline void @@ -288,6 +345,9 @@ { for (size_type __i = 0; __i < _N_words; ++__i) __first_[__i] &= __v.__first_[__i]; +#ifdef DATAFLOW_SANITIZER + merge_labels(__v); +#endif } template @@ -297,6 +357,9 @@ { for (size_type __i = 0; __i < _N_words; ++__i) __first_[__i] |= __v.__first_[__i]; +#ifdef DATAFLOW_SANITIZER + merge_labels(__v); +#endif } template @@ -306,6 +369,9 @@ { for (size_type __i = 0; __i < _N_words; ++__i) __first_[__i] ^= __v.__first_[__i]; +#ifdef DATAFLOW_SANITIZER + merge_labels(__v); +#endif } template @@ -336,7 +402,13 @@ if (__i != __e) __throw_overflow_error("bitset to_ulong overflow error"); +#ifdef DATAFLOW_SANITIZER + unsigned long __r = __first_[0]; + dfsan_set_label(*__i.__label_, &__r, sizeof(__r)); + return __r; +#else return __first_[0]; +#endif } template @@ -344,7 +416,13 @@ unsigned long __bitset<_N_words, _Size>::to_ulong(true_type) const { +#ifdef DATAFLOW_SANITIZER + unsigned long __r = __first_[0]; + dfsan_set_label(__dfsan_labels_[0], &__r, sizeof(__r)); + return __r; +#else return __first_[0]; +#endif } template @@ -372,8 +450,27 @@ unsigned long long __bitset<_N_words, _Size>::to_ullong(true_type, false_type) const { +#ifdef DATAFLOW_SANITIZER + unsigned long __r = __first_[0]; + dfsan_set_label(__dfsan_labels_[0], &__r, sizeof(__r)); + return __r; +#else return __first_[0]; +#endif +} + +#ifdef DATAFLOW_SANITIZER +template +inline +dfsan_label +__bitset<_N_words, _Size>::union_labels() const _NOEXCEPT +{ + dfsan_label __dfsan_label = 0; + for (size_type __i = 0; __i < _Size; ++__i) + __dfsan_label = dfsan_union(__dfsan_label, __dfsan_labels_[__i]); + return __dfsan_label; } +#endif template unsigned long long @@ -382,6 +479,9 @@ unsigned long long __r = __first_[0]; for (size_t __i = 1; __i < sizeof(unsigned long long) / sizeof(__storage_type); ++__i) __r |= static_cast(__first_[__i]) << (sizeof(__storage_type) * CHAR_BIT); +#ifdef DATAFLOW_SANITIZER + dfsan_set_label(union_labels(), &__r, sizeof(__r)); +#endif return __r; } @@ -391,18 +491,41 @@ { // do middle whole words size_type __n = _Size; +#ifdef DATAFLOW_SANITIZER + dfsan_label __dfsan_label = union_labels(); +#endif __const_storage_pointer __p = __first_; for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) - if (~*__p) + if (~*__p) { +#ifdef DATAFLOW_SANITIZER + bool __r = false; + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else return false; +#endif + } // do last partial word if (__n > 0) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - if (~*__p & __m) + if (~*__p & __m) { +#ifdef DATAFLOW_SANITIZER + bool __r = false; + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else return false; +#endif + } } +#ifdef DATAFLOW_SANITIZER + bool __r = true; + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else return true; +#endif } template @@ -411,18 +534,41 @@ { // do middle whole words size_type __n = _Size; +#ifdef DATAFLOW_SANITIZER + dfsan_label __dfsan_label = union_labels(); +#endif __const_storage_pointer __p = __first_; for (; __n >= __bits_per_word; ++__p, __n -= __bits_per_word) - if (*__p) + if (*__p) { +#ifdef DATAFLOW_SANITIZER + bool __r = true; + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else return true; +#endif + } // do last partial word if (__n > 0) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - if (*__p & __m) + if (*__p & __m) { +#ifdef DATAFLOW_SANITIZER + bool __r = true; + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else return true; +#endif + } } +#ifdef DATAFLOW_SANITIZER + bool __r = false; + dfsan_set_label(__dfsan_label, &__r, sizeof(__r)); + return __r; +#else return false; +#endif } template @@ -433,6 +579,9 @@ size_t __h = 0; for (size_type __i = 0; __i < _N_words; ++__i) __h ^= __first_[__i]; +#ifdef DATAFLOW_SANITIZER + dfsan_set_label(union_labels(), &__h, sizeof(__h)); +#endif return __h; } @@ -449,12 +598,20 @@ typedef const __storage_type* __const_storage_pointer; static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); +#ifdef DATAFLOW_SANITIZER + typedef vector::iterator __dfsan_labels_iterator; +#endif + friend class __bit_reference<__bitset>; friend class __bit_const_reference<__bitset>; friend class __bit_iterator<__bitset, false>; friend class __bit_iterator<__bitset, true>; friend struct __bit_array<__bitset>; +#ifdef DATAFLOW_SANITIZER + vector __dfsan_labels_; +#endif + __storage_type __first_; typedef __bit_reference<__bitset> reference; @@ -468,13 +625,29 @@ explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT - {return reference(&__first_, __storage_type(1) << __pos);} + {return reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + &__first_, __storage_type(1) << __pos);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT - {return const_reference(&__first_, __storage_type(1) << __pos);} + {return const_reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + &__first_, __storage_type(1) << __pos);} _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT - {return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + {return iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + &__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT - {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} + {return const_iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + &__first_ + __pos / __bits_per_word, __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset& __v) _NOEXCEPT; @@ -498,6 +671,11 @@ _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT; + +#ifdef DATAFLOW_SANITIZER + dfsan_label union_labels() const _NOEXCEPT; + void merge_labels(const __bitset& __v) _NOEXCEPT; +#endif }; template @@ -505,6 +683,9 @@ _LIBCPP_CONSTEXPR __bitset<1, _Size>::__bitset() _NOEXCEPT : __first_(0) +#ifdef DATAFLOW_SANITIZER + , __dfsan_labels_(_Size, 0) +#endif { } @@ -516,15 +697,32 @@ _Size == __bits_per_word ? static_cast<__storage_type>(__v) : static_cast<__storage_type>(__v) & ((__storage_type(1) << _Size) - 1) ) +#ifdef DATAFLOW_SANITIZER + , __dfsan_labels_(_Size, dfsan_get_label(__v)) +#endif { } +#ifdef DATAFLOW_SANITIZER +template +inline +void +__bitset<1, _Size>::merge_labels(const __bitset& __v) _NOEXCEPT +{ + for (size_type __i = 0; __i < _Size; ++__i) + __dfsan_labels_[__i] = dfsan_union(__dfsan_labels_[__i], __v.__dfsan_labels_[__i]); +} +#endif + template inline void __bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT { __first_ &= __v.__first_; +#ifdef DATAFLOW_SANITIZER + merge_labels(__v); +#endif } template @@ -533,6 +731,9 @@ __bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT { __first_ |= __v.__first_; +#ifdef DATAFLOW_SANITIZER + merge_labels(__v); +#endif } template @@ -541,6 +742,9 @@ __bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT { __first_ ^= __v.__first_; +#ifdef DATAFLOW_SANITIZER + merge_labels(__v); +#endif } template @@ -553,12 +757,31 @@ __first_ &= __m; } +#ifdef DATAFLOW_SANITIZER +template +inline +dfsan_label +__bitset<1, _Size>::union_labels() const _NOEXCEPT +{ + dfsan_label __dfsan_label = 0; + for (size_type __i = 0; __i < _Size; ++__i) + __dfsan_label = dfsan_union(__dfsan_label, __dfsan_labels_[__i]); + return __dfsan_label; +} +#endif + template inline unsigned long __bitset<1, _Size>::to_ulong() const { +#ifdef DATAFLOW_SANITIZER + unsigned long __r = __first_; + dfsan_set_label(union_labels(), &__r, sizeof(__r)); + return __r; +#else return __first_; +#endif } template @@ -566,7 +789,13 @@ unsigned long long __bitset<1, _Size>::to_ullong() const { +#ifdef DATAFLOW_SANITIZER + unsigned long long __r = __first_; + dfsan_set_label(union_labels(), &__r, sizeof(__r)); + return __r; +#else return __first_; +#endif } template @@ -575,7 +804,13 @@ __bitset<1, _Size>::all() const _NOEXCEPT { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); +#ifdef DATAFLOW_SANITIZER + bool __r = !(~__first_ & __m); + dfsan_set_label(union_labels(), &__r, sizeof(__r)); + return __r; +#else return !(~__first_ & __m); +#endif } template @@ -584,7 +819,13 @@ __bitset<1, _Size>::any() const _NOEXCEPT { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size); +#ifdef DATAFLOW_SANITIZER + bool __r = __first_ & __m; + dfsan_set_label(union_labels(), &__r, sizeof(__r)); + return __r; +#else return __first_ & __m; +#endif } template @@ -592,7 +833,13 @@ size_t __bitset<1, _Size>::__hash_code() const _NOEXCEPT { +#ifdef DATAFLOW_SANITIZER + size_t __r = __first_; + dfsan_set_label(union_labels(), &__r, sizeof(__r)); + return __r; +#else return __first_; +#endif } template <> @@ -606,6 +853,9 @@ typedef __bitset __self; typedef __storage_type* __storage_pointer; typedef const __storage_type* __const_storage_pointer; +#ifdef DATAFLOW_SANITIZER + typedef vector::iterator __dfsan_labels_iterator; +#endif static const unsigned __bits_per_word = static_cast(sizeof(__storage_type) * CHAR_BIT); friend class __bit_reference<__bitset>; @@ -625,13 +875,29 @@ explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT - {return reference(nullptr, 1);} + {return reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_iterator(), +#endif + nullptr, 1);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT - {return const_reference(nullptr, 1);} + {return const_reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_iterator(), +#endif + nullptr, 1);} _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t) _NOEXCEPT - {return iterator(nullptr, 0);} + {return iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_iterator(), +#endif + nullptr, 0);} _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t) const _NOEXCEPT - {return const_iterator(nullptr, 0);} + {return const_iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_iterator(), +#endif + nullptr, 0);} _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset&) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY void operator|=(const __bitset&) _NOEXCEPT {} @@ -775,10 +1041,15 @@ for (; __i < _Mp; ++__i) { _CharT __c = __str[_Mp - 1 - __i]; +#ifdef DATAFLOW_SANITIZER + bool __b = __c == __zero; + (*this)[__i] = __b; +#else if (__c == __zero) (*this)[__i] = false; else (*this)[__i] = true; +#endif } _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); } @@ -953,8 +1224,20 @@ basic_string<_CharT, _Traits, _Allocator> __r(_Size, __zero); for (size_t __i = 0; __i < _Size; ++__i) { - if ((*this)[__i]) +#ifdef DATAFLOW_SANITIZER + bool __b = (*this)[__i]; + if (__b) { + dfsan_set_label(dfsan_get_label(__b), &__one, sizeof(__one)); __r[_Size - 1 - __i] = __one; + } else { + dfsan_set_label(dfsan_get_label(__b), &__zero, sizeof(__zero)); + __r[_Size - 1 - __i] = __zero; + } +#else + if ((*this)[__i]) { + __r[_Size - 1 - __i] = __one; + } +#endif } return __r; } diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -2184,10 +2184,19 @@ typedef allocator_traits<__storage_allocator> __storage_traits; typedef typename __storage_traits::pointer __storage_pointer; typedef typename __storage_traits::const_pointer __const_storage_pointer; + +#ifdef DATAFLOW_SANITIZER + typedef vector::iterator __dfsan_labels_iterator; +#endif __storage_pointer __begin_; size_type __size_; __compressed_pair __cap_alloc_; + +#ifdef DATAFLOW_SANITIZER + vector __dfsan_labels_; +#endif + public: typedef __bit_reference reference; typedef __bit_const_reference const_reference; @@ -2449,16 +2458,32 @@ void __append(size_type __n, const_reference __x); _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_type __pos) _NOEXCEPT - {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + {return reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY const_reference __make_ref(size_type __pos) const _NOEXCEPT - {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} + {return const_reference( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);} _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_type __pos) _NOEXCEPT - {return iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} + {return iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_type __pos) const _NOEXCEPT - {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} + {return const_iterator( +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.begin() + __pos, +#endif + __begin_ + __pos / __bits_per_word, static_cast(__pos % __bits_per_word));} _LIBCPP_INLINE_VISIBILITY iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT {return begin() + (__p - cbegin());} @@ -2535,6 +2560,9 @@ this->__begin_ = __storage_traits::allocate(this->__alloc(), __n); this->__size_ = 0; this->__cap() = __n; +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_.resize(__n, 0); +#endif } template @@ -2880,7 +2908,11 @@ #endif : __begin_(__v.__begin_), __size_(__v.__size_), - __cap_alloc_(_VSTD::move(__v.__cap_alloc_)) { +#ifdef DATAFLOW_SANITIZER + __dfsan_labels_(_VSTD::move(__v.__dfsan_labels_)), +#endif + __cap_alloc_(_VSTD::move(__v.__cap_alloc_)) +{ __v.__begin_ = nullptr; __v.__size_ = 0; __v.__cap() = 0; @@ -2897,6 +2929,9 @@ this->__begin_ = __v.__begin_; this->__size_ = __v.__size_; this->__cap() = __v.__cap(); +#ifdef DATAFLOW_SANITIZER + this->__dfsan_labels_ = std::move(__v.__dfsan_labels_); +#endif __v.__begin_ = nullptr; __v.__cap() = __v.__size_ = 0; } @@ -2938,6 +2973,9 @@ this->__begin_ = __c.__begin_; this->__size_ = __c.__size_; this->__cap() = __c.__cap(); +#ifdef DATAFLOW_SANITIZER + this->__dfsan_labels_ = std::move(__c.__dfsan_labels_); +#endif __c.__begin_ = nullptr; __c.__cap() = __c.__size_ = 0; } @@ -3234,6 +3272,9 @@ _VSTD::swap(this->__cap(), __x.__cap()); _VSTD::__swap_allocator(this->__alloc(), __x.__alloc(), integral_constant()); +#ifdef DATAFLOW_SANITIZER + _VSTD::swap(__dfsan_labels_, __x.__dfsan_labels_); +#endif } template