diff options
Diffstat (limited to 'gcc-4.9/libstdc++-v3/include')
23 files changed, 999 insertions, 183 deletions
diff --git a/gcc-4.9/libstdc++-v3/include/Makefile.am b/gcc-4.9/libstdc++-v3/include/Makefile.am index 85b0f31a0..61aa2c43f 100644 --- a/gcc-4.9/libstdc++-v3/include/Makefile.am +++ b/gcc-4.9/libstdc++-v3/include/Makefile.am @@ -948,6 +948,7 @@ stamp-bits: ${bits_headers} stamp-bits-sup: stamp-bits ${bits_sup_headers} @-cd ${bits_builddir} && $(LN_S) $? . 2>/dev/null + @-cd ${bits_builddir} && rm -f stamp-bits && $(STAMP) stamp-bits @$(STAMP) stamp-bits-sup stamp-c_base: ${c_base_headers} diff --git a/gcc-4.9/libstdc++-v3/include/Makefile.in b/gcc-4.9/libstdc++-v3/include/Makefile.in index c72658346..e66f0dce0 100644 --- a/gcc-4.9/libstdc++-v3/include/Makefile.in +++ b/gcc-4.9/libstdc++-v3/include/Makefile.in @@ -1367,6 +1367,7 @@ stamp-bits: ${bits_headers} stamp-bits-sup: stamp-bits ${bits_sup_headers} @-cd ${bits_builddir} && $(LN_S) $? . 2>/dev/null + @-cd ${bits_builddir} && rm -f stamp-bits && $(STAMP) stamp-bits @$(STAMP) stamp-bits-sup stamp-c_base: ${c_base_headers} diff --git a/gcc-4.9/libstdc++-v3/include/backward/hashtable.h b/gcc-4.9/libstdc++-v3/include/backward/hashtable.h index 86121af8c..158f2a5bf 100644 --- a/gcc-4.9/libstdc++-v3/include/backward/hashtable.h +++ b/gcc-4.9/libstdc++-v3/include/backward/hashtable.h @@ -125,7 +125,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Hashtable_iterator(_Node* __n, _Hashtable* __tab) : _M_cur(__n), _M_ht(__tab) { } - _Hashtable_iterator() { } + _Hashtable_iterator() + : _M_cur(0), _M_ht(0) { } reference operator*() const diff --git a/gcc-4.9/libstdc++-v3/include/bits/deque.tcc b/gcc-4.9/libstdc++-v3/include/bits/deque.tcc index ebf5d3a0a..972176546 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/deque.tcc +++ b/gcc-4.9/libstdc++-v3/include/bits/deque.tcc @@ -150,6 +150,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque<_Tp, _Alloc>:: emplace(const_iterator __position, _Args&&... __args) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("emplace() at invalid position")); +#endif if (__position._M_cur == this->_M_impl._M_start._M_cur) { emplace_front(std::forward<_Args>(__args)...); @@ -177,6 +181,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(iterator __position, const value_type& __x) #endif { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif if (__position._M_cur == this->_M_impl._M_start._M_cur) { push_front(__x); @@ -198,6 +206,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque<_Tp, _Alloc>:: _M_erase(iterator __position) { +#if __google_stl_debug_deque + if (__position < this->begin() || __position >= this->end()) + __throw_logic_error("erase() at invalid position"); +#endif iterator __next = __position; ++__next; const difference_type __index = __position - begin(); @@ -221,6 +233,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque<_Tp, _Alloc>:: _M_erase(iterator __first, iterator __last) { +#if __google_stl_debug_deque + if (__first < this->begin() || __first > __last || __last > this->end()) + __throw_logic_error("erase() invalid range"); +#endif if (__first == __last) return __first; else if (__first == begin() && __last == end()) diff --git a/gcc-4.9/libstdc++-v3/include/bits/hashtable.h b/gcc-4.9/libstdc++-v3/include/bits/hashtable.h index 22e17d29d..9b6394c4e 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/hashtable.h +++ b/gcc-4.9/libstdc++-v3/include/bits/hashtable.h @@ -316,14 +316,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type _M_element_count; _RehashPolicy _M_rehash_policy; + // A single bucket used when only need for 1 bucket. Especially + // interesting in move semantic to leave hashtable with only 1 buckets + // which is not allocated so that we can have those operations noexcept + // qualified. + // Note that we can't leave hashtable with 0 bucket without adding + // numerous checks in the code to avoid 0 modulus. + __bucket_type _M_single_bucket; + + bool + _M_uses_single_bucket(__bucket_type* __bkts) const + { return __builtin_expect(_M_buckets == &_M_single_bucket, false); } + + bool + _M_uses_single_bucket() const + { return _M_uses_single_bucket(_M_buckets); } + __hashtable_alloc& _M_base_alloc() { return *this; } - using __hashtable_alloc::_M_deallocate_buckets; + __bucket_type* + _M_allocate_buckets(size_type __n) + { + if (__builtin_expect(__n == 1, false)) + { + _M_single_bucket = nullptr; + return &_M_single_bucket; + } + + return __hashtable_alloc::_M_allocate_buckets(__n); + } + + void + _M_deallocate_buckets(__bucket_type* __bkts, size_type __n) + { + if (_M_uses_single_bucket(__bkts)) + return; + + __hashtable_alloc::_M_deallocate_buckets(__bkts, __n); + } void _M_deallocate_buckets() - { this->_M_deallocate_buckets(_M_buckets, _M_bucket_count); } + { _M_deallocate_buckets(_M_buckets, _M_bucket_count); } // Gets bucket begin, deals with the fact that non-empty buckets contain // their before begin node. @@ -703,11 +738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type erase(const key_type& __k) - { - if (__builtin_expect(_M_bucket_count == 0, false)) - return 0; - return _M_erase(__unique_keys(), __k); - } + { return _M_erase(__unique_keys(), __k); } iterator erase(const_iterator, const_iterator); @@ -768,7 +799,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_rehash_policy() { _M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint); - _M_buckets = this->_M_allocate_buckets(_M_bucket_count); + _M_buckets = _M_allocate_buckets(_M_bucket_count); } template<typename _Key, typename _Value, @@ -796,7 +827,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems), __bucket_hint)); - _M_buckets = this->_M_allocate_buckets(_M_bucket_count); + _M_buckets = _M_allocate_buckets(_M_bucket_count); __try { for (; __f != __l; ++__f) @@ -833,9 +864,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Replacement allocator cannot free existing storage. this->_M_deallocate_nodes(_M_begin()); - if (__builtin_expect(_M_bucket_count != 0, true)) - _M_deallocate_buckets(); - _M_reset(); + _M_before_begin._M_nxt = nullptr; + _M_deallocate_buckets(); + _M_buckets = nullptr; std::__alloc_on_copy(__this_alloc, __that_alloc); __hashtable_base::operator=(__ht); _M_bucket_count = __ht._M_bucket_count; @@ -867,7 +898,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (_M_bucket_count != __ht._M_bucket_count) { __former_buckets = _M_buckets; - _M_buckets = this->_M_allocate_buckets(__ht._M_bucket_count); + _M_buckets = _M_allocate_buckets(__ht._M_bucket_count); _M_bucket_count = __ht._M_bucket_count; } else @@ -885,8 +916,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION [&__roan](const __node_type* __n) { return __roan(__n->_M_v()); }); if (__former_buckets) - this->_M_deallocate_buckets(__former_buckets, - __former_bucket_count); + _M_deallocate_buckets(__former_buckets, __former_bucket_count); } __catch(...) { @@ -917,7 +947,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __bucket_type* __buckets = nullptr; if (!_M_buckets) - _M_buckets = __buckets = this->_M_allocate_buckets(_M_bucket_count); + _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count); __try { @@ -964,8 +994,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_reset() noexcept { _M_rehash_policy._M_reset(); - _M_bucket_count = 0; - _M_buckets = nullptr; + _M_bucket_count = 1; + _M_single_bucket = nullptr; + _M_buckets = &_M_single_bucket; _M_before_begin._M_nxt = nullptr; _M_element_count = 0; } @@ -980,12 +1011,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_move_assign(_Hashtable&& __ht, std::true_type) { this->_M_deallocate_nodes(_M_begin()); - if (__builtin_expect(_M_bucket_count != 0, true)) - _M_deallocate_buckets(); - + _M_deallocate_buckets(); __hashtable_base::operator=(std::move(__ht)); _M_rehash_policy = __ht._M_rehash_policy; - _M_buckets = __ht._M_buckets; + if (!__ht._M_uses_single_bucket()) + _M_buckets = __ht._M_buckets; + else + { + _M_buckets = &_M_single_bucket; + _M_single_bucket = __ht._M_single_bucket; + } _M_bucket_count = __ht._M_bucket_count; _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt; _M_element_count = __ht._M_element_count; @@ -1019,7 +1054,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (_M_bucket_count != __ht._M_bucket_count) { __former_buckets = _M_buckets; - _M_buckets = this->_M_allocate_buckets(__ht._M_bucket_count); + _M_buckets = _M_allocate_buckets(__ht._M_bucket_count); _M_bucket_count = __ht._M_bucket_count; } else @@ -1093,10 +1128,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) { + // Update, if necessary, buckets if __ht is using its single bucket. + if (__ht._M_uses_single_bucket()) + { + _M_buckets = &_M_single_bucket; + _M_single_bucket = __ht._M_single_bucket; + } + // Update, if necessary, bucket pointing to before begin that hasn't // moved. if (_M_begin()) _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; + __ht._M_reset(); } @@ -1139,7 +1182,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (__ht._M_node_allocator() == this->_M_node_allocator()) { - _M_buckets = __ht._M_buckets; + if (__ht._M_uses_single_bucket()) + { + _M_buckets = &_M_single_bucket; + _M_single_bucket = __ht._M_single_bucket; + } + else + _M_buckets = __ht._M_buckets; + _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt; // Update, if necessary, bucket pointing to before begin that hasn't // moved. @@ -1189,15 +1239,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator()); std::swap(_M_rehash_policy, __x._M_rehash_policy); - std::swap(_M_buckets, __x._M_buckets); + + // Deal properly with potentially moved instances. + if (this->_M_uses_single_bucket()) + { + if (!__x._M_uses_single_bucket()) + { + _M_buckets = __x._M_buckets; + __x._M_buckets = &__x._M_single_bucket; + } + } + else if (__x._M_uses_single_bucket()) + { + __x._M_buckets = _M_buckets; + _M_buckets = &_M_single_bucket; + } + else + std::swap(_M_buckets, __x._M_buckets); + std::swap(_M_bucket_count, __x._M_bucket_count); std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt); std::swap(_M_element_count, __x._M_element_count); + std::swap(_M_single_bucket, __x._M_single_bucket); // Fix buckets containing the _M_before_begin pointers that can't be // swapped. if (_M_begin()) _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin; + if (__x._M_begin()) __x._M_buckets[__x._M_bucket_index(__x._M_begin())] = &__x._M_before_begin; @@ -1230,9 +1299,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: find(const key_type& __k) { - if (__builtin_expect(_M_bucket_count == 0, false)) - return end(); - __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); @@ -1250,9 +1316,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: find(const key_type& __k) const { - if (__builtin_expect(_M_bucket_count == 0, false)) - return end(); - __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); @@ -1270,9 +1333,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: count(const key_type& __k) const { - if (__builtin_expect(_M_bucket_count == 0, false)) - return 0; - __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_bucket_begin(__n); @@ -1287,7 +1347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else if (__result) // All equivalent values are next to each other, if we // found a non-equivalent value after an equivalent one it - // means that we won't find any more equivalent values. + // means that we won't find any new equivalent value. break; if (!__p->_M_nxt || _M_bucket_index(__p->_M_next()) != __n) break; @@ -1311,9 +1371,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: equal_range(const key_type& __k) { - if (__builtin_expect(_M_bucket_count == 0, false)) - return std::make_pair(end(), end()); - __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); @@ -1347,9 +1404,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: equal_range(const key_type& __k) const { - if (__builtin_expect(_M_bucket_count == 0, false)) - return std::make_pair(end(), end()); - __hash_code __code = this->_M_hash_code(__k); std::size_t __n = _M_bucket_index(__k, __code); __node_type* __p = _M_find_node(__n, __k, __code); @@ -1944,7 +1998,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_rehash_aux(size_type __n, std::true_type) { - __bucket_type* __new_buckets = this->_M_allocate_buckets(__n); + __bucket_type* __new_buckets = _M_allocate_buckets(__n); __node_type* __p = _M_begin(); _M_before_begin._M_nxt = nullptr; std::size_t __bbegin_bkt = 0; @@ -1969,8 +2023,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __p = __next; } - if (__builtin_expect(_M_bucket_count != 0, true)) - _M_deallocate_buckets(); + _M_deallocate_buckets(); _M_bucket_count = __n; _M_buckets = __new_buckets; } @@ -1986,7 +2039,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _H1, _H2, _Hash, _RehashPolicy, _Traits>:: _M_rehash_aux(size_type __n, std::false_type) { - __bucket_type* __new_buckets = this->_M_allocate_buckets(__n); + __bucket_type* __new_buckets = _M_allocate_buckets(__n); __node_type* __p = _M_begin(); _M_before_begin._M_nxt = nullptr; @@ -2060,8 +2113,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __new_buckets[__next_bkt] = __prev_p; } - if (__builtin_expect(_M_bucket_count != 0, true)) - _M_deallocate_buckets(); + _M_deallocate_buckets(); _M_bucket_count = __n; _M_buckets = __new_buckets; } diff --git a/gcc-4.9/libstdc++-v3/include/bits/regex_automaton.tcc b/gcc-4.9/libstdc++-v3/include/bits/regex_automaton.tcc index 759b053c5..6e68fca82 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/regex_automaton.tcc +++ b/gcc-4.9/libstdc++-v3/include/bits/regex_automaton.tcc @@ -35,7 +35,7 @@ namespace __detail _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef _GLIBCXX_DEBUG - std::ostream& + inline std::ostream& _State_base::_M_print(std::ostream& ostr) const { switch (_M_opcode) @@ -66,7 +66,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // Prints graphviz dot commands for state. - std::ostream& + inline std::ostream& _State_base::_M_dot(std::ostream& __ostr, _StateIdT __id) const { switch (_M_opcode) @@ -197,20 +197,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _M_insert_state() never return -1 auto __id = _M_nfa._M_insert_state(__dup); __m[__u] = __id; - if (__u == _M_end) - continue; - if (__dup._M_next != _S_invalid_state_id && __m[__dup._M_next] == -1) - __stack.push(__dup._M_next); if (__dup._M_opcode == _S_opcode_alternative || __dup._M_opcode == _S_opcode_subexpr_lookahead) if (__dup._M_alt != _S_invalid_state_id && __m[__dup._M_alt] == -1) __stack.push(__dup._M_alt); + if (__u == _M_end) + continue; + if (__dup._M_next != _S_invalid_state_id && __m[__dup._M_next] == -1) + __stack.push(__dup._M_next); } - long __size = static_cast<long>(__m.size()); - for (long __k = 0; __k < __size; __k++) + for (auto __v : __m) { - long __v; - if ((__v = __m[__k]) == -1) + if (__v == -1) continue; auto& __ref = _M_nfa[__v]; if (__ref._M_next != _S_invalid_state_id) diff --git a/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.h b/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.h index f5a198f65..af76f5505 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.h +++ b/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.h @@ -369,15 +369,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } + // __neg should be true for \D, \S and \W only. void - _M_add_character_class(const _StringT& __s) + _M_add_character_class(const _StringT& __s, bool __neg) { auto __mask = _M_traits.lookup_classname(__s.data(), __s.data() + __s.size(), __icase); if (__mask == 0) __throw_regex_error(regex_constants::error_ctype); - _M_class_set |= __mask; + if (!__neg) + _M_class_set |= __mask; + else + _M_neg_class_set.push_back(__mask); #ifdef _GLIBCXX_DEBUG _M_is_ready = false; #endif @@ -387,7 +391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_make_range(_CharT __l, _CharT __r) { _M_range_set.push_back(make_pair(_M_translator._M_transform(__l), - _M_translator._M_transform(__r))); + _M_translator._M_transform(__r))); #ifdef _GLIBCXX_DEBUG _M_is_ready = false; #endif @@ -435,6 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::vector<_CharT> _M_char_set; std::vector<_StringT> _M_equiv_set; std::vector<pair<_StrTransT, _StrTransT>> _M_range_set; + std::vector<_CharClassT> _M_neg_class_set; _CharClassT _M_class_set; _TransT _M_translator; const _TraitsT& _M_traits; diff --git a/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.tcc b/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.tcc index 128dac12b..14e40c0cd 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/gcc-4.9/libstdc++-v3/include/bits/regex_compiler.tcc @@ -397,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1); _BracketMatcher<_TraitsT, __icase, __collate> __matcher (_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits); - __matcher._M_add_character_class(_M_value); + __matcher._M_add_character_class(_M_value, false); __matcher._M_ready(); _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_matcher(std::move(__matcher)))); @@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION else if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) __matcher._M_add_equivalence_class(_M_value); else if (_M_match_token(_ScannerT::_S_token_char_class_name)) - __matcher._M_add_character_class(_M_value); + __matcher._M_add_character_class(_M_value, false); else if (_M_try_char()) // [a { auto __ch = _M_value[0]; @@ -451,6 +451,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } __matcher._M_add_char(__ch); } + else if (_M_match_token(_ScannerT::_S_token_quoted_class)) + __matcher._M_add_character_class(_M_value, + _M_ctype.is(_CtypeT::upper, + _M_value[0])); else __throw_regex_error(regex_constants::error_brack); } @@ -527,6 +531,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_traits.transform_primary(&__ch, &__ch+1)) != _M_equiv_set.end()) __ret = true; + else + { + for (auto& __it : _M_neg_class_set) + if (!_M_traits.isctype(__ch, __it)) + { + __ret = true; + break; + } + } } if (_M_is_non_matching) return !__ret; diff --git a/gcc-4.9/libstdc++-v3/include/bits/regex_executor.tcc b/gcc-4.9/libstdc++-v3/include/bits/regex_executor.tcc index 68a5e0490..052302b91 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/regex_executor.tcc +++ b/gcc-4.9/libstdc++-v3/include/bits/regex_executor.tcc @@ -120,10 +120,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (_M_match_queue->empty()) break; _M_visited->assign(_M_visited->size(), false); - auto _M_old_queue = std::move(*_M_match_queue); - for (auto __task : _M_old_queue) + auto __old_queue = std::move(*_M_match_queue); + for (auto& __task : __old_queue) { - _M_cur_results = __task.second; + _M_cur_results = std::move(__task.second); _M_dfs<__match_mode>(__task.first); } if (!__match_mode) diff --git a/gcc-4.9/libstdc++-v3/include/bits/stl_algo.h b/gcc-4.9/libstdc++-v3/include/bits/stl_algo.h index 4c6ca8a72..104ab8685 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/stl_algo.h +++ b/gcc-4.9/libstdc++-v3/include/bits/stl_algo.h @@ -199,6 +199,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // count_if // search +// Local modification: if __google_stl_debug_compare is defined to +// non-zero value, check sort predicate for strict weak ordering. +// Google ref b/1731200. +#if __google_stl_debug_compare + template<typename _Compare> + struct _CheckedCompare { + _Compare _M_compare; + + _CheckedCompare(const _Compare & __comp): _M_compare(__comp) { } + + template <typename _Tp> + bool operator()(const _Tp& __x, const _Tp& __y) { + if (_M_compare(__x, __x)) + __throw_runtime_error("strict weak ordering: (__x LT __x) != false"); + if (_M_compare(__y, __y)) + __throw_runtime_error("strict weak ordering: (__y LT __y) != false"); + bool lt = _M_compare(__x, __y); + if (lt && _M_compare(__y, __x)) + __throw_runtime_error("strict weak ordering: ((__x LT __y) && (__y LT __x)) != false"); + return lt; + } + + // Different types; can't perform any checks. + template <typename _Tp1, typename _Tp2> + bool operator()(const _Tp1& __x, const _Tp2& __y) { + return _M_compare(__x, __y); + } + }; +# define __CheckedCompare(__comp) _CheckedCompare<__typeof__(__comp)>(__comp) +#else +# define __CheckedCompare(__comp) __comp +#endif + + template<typename _ForwardIterator1, typename _ForwardIterator2, typename _BinaryPredicate> _ForwardIterator1 @@ -1811,7 +1845,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::__partial_sort_copy(__first, __last, __result_first, __result_last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } /// This is a helper function for the sort routine. @@ -2033,7 +2067,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __val, __comp); return std::__lower_bound(__first, __last, __val, - __gnu_cxx::__ops::__iter_comp_val(__comp)); + __gnu_cxx::__ops::__iter_comp_val(__CheckedCompare(__comp))); } template<typename _ForwardIterator, typename _Tp, typename _Compare> @@ -2122,7 +2156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __val, __comp); return std::__upper_bound(__first, __last, __val, - __gnu_cxx::__ops::__val_comp_iter(__comp)); + __gnu_cxx::__ops::__val_comp_iter(__CheckedCompare(__comp))); } template<typename _ForwardIterator, typename _Tp, @@ -2237,8 +2271,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __val, __comp); return std::__equal_range(__first, __last, __val, - __gnu_cxx::__ops::__iter_comp_val(__comp), - __gnu_cxx::__ops::__val_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_val(__CheckedCompare(__comp)), + __gnu_cxx::__ops::__val_comp_iter(__CheckedCompare(__comp))); } /** @@ -2307,7 +2341,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ForwardIterator __i = std::__lower_bound(__first, __last, __val, - __gnu_cxx::__ops::__iter_comp_val(__comp)); + __gnu_cxx::__ops::__iter_comp_val(__CheckedCompare(__comp))); return __i != __last && !bool(__comp(__val, *__i)); } @@ -2638,7 +2672,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_sorted_pred(__middle, __last, __comp); std::__inplace_merge(__first, __middle, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } @@ -2890,7 +2924,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_sorted_set_pred(__first2, __last2, __first1, __comp); return std::__includes(__first1, __last1, __first2, __last2, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } // nth_element @@ -2997,7 +3031,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); return std::__next_permutation - (__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); + (__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _BidirectionalIterator, typename _Compare> @@ -3095,7 +3129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); return std::__prev_permutation(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } // replace @@ -3282,7 +3316,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); return std::__is_sorted_until(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } /** @@ -3430,7 +3464,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_valid_range(__first, __last); return std::__minmax_element(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } // N2722 + DR 915. @@ -4570,7 +4604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__middle, __last); std::__partial_sort(__first, __middle, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } /** @@ -4645,7 +4679,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO std::__introselect(__first, __nth, __last, std::__lg(__last - __first) * 2, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } /** @@ -4704,7 +4738,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_RandomAccessIterator>::value_type>) __glibcxx_requires_valid_range(__first, __last); - std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); + std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _InputIterator1, typename _InputIterator2, @@ -4821,7 +4855,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return _GLIBCXX_STD_A::__merge(__first1, __last1, __first2, __last2, __result, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _RandomAccessIterator, typename _Compare> @@ -4908,7 +4942,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first, __last); _GLIBCXX_STD_A::__stable_sort(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _InputIterator1, typename _InputIterator2, @@ -5033,7 +5067,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return _GLIBCXX_STD_A::__set_union(__first1, __last1, __first2, __last2, __result, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _InputIterator1, typename _InputIterator2, @@ -5145,7 +5179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return _GLIBCXX_STD_A::__set_intersection(__first1, __last1, __first2, __last2, __result, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _InputIterator1, typename _InputIterator2, @@ -5263,7 +5297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return _GLIBCXX_STD_A::__set_difference(__first1, __last1, __first2, __last2, __result, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _InputIterator1, typename _InputIterator2, @@ -5390,7 +5424,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO return _GLIBCXX_STD_A::__set_symmetric_difference(__first1, __last1, __first2, __last2, __result, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__CheckedCompare(__comp))); } template<typename _ForwardIterator, typename _Compare> @@ -5450,7 +5484,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first, __last); return _GLIBCXX_STD_A::__min_element(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } template<typename _ForwardIterator, typename _Compare> @@ -5509,7 +5543,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO __glibcxx_requires_valid_range(__first, __last); return _GLIBCXX_STD_A::__max_element(__first, __last, - __gnu_cxx::__ops::__iter_comp_iter(__comp)); + __gnu_cxx::__ops::__iter_comp_iter(__comp)); } _GLIBCXX_END_NAMESPACE_ALGO diff --git a/gcc-4.9/libstdc++-v3/include/bits/stl_bvector.h b/gcc-4.9/libstdc++-v3/include/bits/stl_bvector.h index 996eb1a8d..86375cb9b 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/stl_bvector.h +++ b/gcc-4.9/libstdc++-v3/include/bits/stl_bvector.h @@ -471,11 +471,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER #endif ~_Bvector_base() - { this->_M_deallocate(); } + { + this->_M_deallocate(); +#if __google_stl_debug_bvector + __builtin_memset(this, 0xcd, sizeof(*this)); +#endif + } protected: _Bvector_impl _M_impl; +#if __google_stl_debug_bvector + bool _M_is_valid() const + { + return (this->_M_impl._M_start._M_p == 0 + && this->_M_impl._M_finish._M_p == 0 + && this->_M_impl._M_end_of_storage == 0) + || (this->_M_impl._M_start._M_p <= this->_M_impl._M_finish._M_p + && this->_M_impl._M_finish._M_p <= this->_M_impl._M_end_of_storage + && (this->_M_impl._M_start._M_p < this->_M_impl._M_end_of_storage + || (this->_M_impl._M_start._M_p == this->_M_impl._M_end_of_storage + && this->_M_impl._M_start._M_offset == 0 + && this->_M_impl._M_finish._M_offset == 0))); + } +#endif + _Bit_type* _M_allocate(size_t __n) { return _M_impl.allocate(_S_nword(__n)); } @@ -631,6 +651,10 @@ template<typename _Alloc> vector& operator=(const vector& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("op=() on corrupt (dangling?) vector"); +#endif if (&__x == this) return *this; if (__x.size() > capacity()) @@ -647,6 +671,10 @@ template<typename _Alloc> vector& operator=(vector&& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("op=() on corrupt (dangling?) vector"); +#endif // NB: DR 1204. // NB: DR 675. this->clear(); @@ -668,19 +696,35 @@ template<typename _Alloc> // or not the type is an integer. void assign(size_type __n, const bool& __x) - { _M_fill_assign(__n, __x); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign() on corrupt (dangling?) vector"); +#endif + _M_fill_assign(__n, __x); + } #if __cplusplus >= 201103L template<typename _InputIterator, typename = std::_RequireInputIter<_InputIterator>> void assign(_InputIterator __first, _InputIterator __last) - { _M_assign_dispatch(__first, __last, __false_type()); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign() on corrupt (dangling?) vector"); +#endif + _M_assign_dispatch(__first, __last, __false_type()); + } #else template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign() on corrupt (dangling?) vector"); +#endif typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } @@ -694,19 +738,43 @@ template<typename _Alloc> iterator begin() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } const_iterator begin() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } iterator end() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } const_iterator end() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT @@ -727,11 +795,23 @@ template<typename _Alloc> #if __cplusplus >= 201103L const_iterator cbegin() const noexcept - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("cbegin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } const_iterator cend() const noexcept - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("cend() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } const_reverse_iterator crbegin() const noexcept @@ -749,6 +829,10 @@ template<typename _Alloc> size_type max_size() const _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("max_size() on corrupt (dangling?) vector"); +#endif const size_type __isize = __gnu_cxx::__numeric_traits<difference_type>::__max - int(_S_word_bit) + 1; @@ -769,6 +853,11 @@ template<typename _Alloc> reference operator[](size_type __n) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("operator[] on corrupt (dangling?) vector"); + _M_range_check(__n); +#endif return *iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } @@ -776,6 +865,11 @@ template<typename _Alloc> const_reference operator[](size_type __n) const { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("operator[] on corrupt (dangling?) vector"); + _M_range_check(__n); +#endif return *const_iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } @@ -794,11 +888,21 @@ template<typename _Alloc> public: reference at(size_type __n) - { _M_range_check(__n); return (*this)[__n]; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("at() on corrupt (dangling?) vector"); +#endif + _M_range_check(__n); return (*this)[__n]; } const_reference at(size_type __n) const - { _M_range_check(__n); return (*this)[__n]; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("at() on corrupt (dangling?) vector"); +#endif + _M_range_check(__n); return (*this)[__n]; } void reserve(size_type __n) @@ -811,19 +915,47 @@ template<typename _Alloc> reference front() - { return *begin(); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("front() on corrupt (dangling?) vector"); + _M_range_check(0); +#endif + return *begin(); + } const_reference front() const - { return *begin(); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("front() on corrupt (dangling?) vector"); + _M_range_check(0); +#endif + return *begin(); + } reference back() - { return *(end() - 1); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("back() on corrupt (dangling?) vector"); + _M_range_check(0); +#endif + return *(end() - 1); + } const_reference back() const - { return *(end() - 1); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("back() on corrupt (dangling?) vector"); + _M_range_check(0); +#endif + return *(end() - 1); + } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. @@ -836,6 +968,10 @@ template<typename _Alloc> void push_back(bool __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("push_back() on corrupt (dangling?) vector"); +#endif if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) *this->_M_impl._M_finish++ = __x; else @@ -845,6 +981,10 @@ template<typename _Alloc> void swap(vector& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid() || !__x._M_is_valid()) + __throw_logic_error("swap() on corrupt (dangling?) vector"); +#endif std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, @@ -872,6 +1012,12 @@ template<typename _Alloc> insert(iterator __position, const bool& __x = bool()) #endif { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif const difference_type __n = __position - begin(); if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage && __position == end()) @@ -888,6 +1034,12 @@ template<typename _Alloc> insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif difference_type __offset = __position - cbegin(); _M_insert_dispatch(__position._M_const_cast(), __first, __last, __false_type()); @@ -899,6 +1051,12 @@ template<typename _Alloc> insert(iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } @@ -908,6 +1066,12 @@ template<typename _Alloc> iterator insert(const_iterator __position, size_type __n, const bool& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif difference_type __offset = __position - cbegin(); _M_fill_insert(__position._M_const_cast(), __n, __x); return begin() + __offset; @@ -915,7 +1079,15 @@ template<typename _Alloc> #else void insert(iterator __position, size_type __n, const bool& __x) - { _M_fill_insert(__position, __n, __x); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif + _M_fill_insert(__position, __n, __x); + } #endif #if __cplusplus >= 201103L @@ -926,7 +1098,14 @@ template<typename _Alloc> void pop_back() - { --this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("pop_back() on corrupt (dangling?) vector"); + _M_range_check(0); +#endif + --this->_M_impl._M_finish; + } iterator #if __cplusplus >= 201103L @@ -934,7 +1113,15 @@ template<typename _Alloc> #else erase(iterator __position) #endif - { return _M_erase(__position._M_const_cast()); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("erase() on corrupt (dangling?) vector"); + if (__position < this->begin() || __position >= this->end()) + __throw_logic_error("erase() at invalid position"); +#endif + return _M_erase(__position._M_const_cast()); + } iterator #if __cplusplus >= 201103L @@ -942,7 +1129,15 @@ template<typename _Alloc> #else erase(iterator __first, iterator __last) #endif - { return _M_erase(__first._M_const_cast(), __last._M_const_cast()); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("erase() on corrupt (dangling?) vector"); + if (__first < this->begin() || __first > __last || __last > this->end()) + __throw_logic_error("erase() invalid range"); +#endif + return _M_erase(__first._M_const_cast(), __last._M_const_cast()); + } void resize(size_type __new_size, bool __x = bool()) @@ -956,12 +1151,22 @@ template<typename _Alloc> #if __cplusplus >= 201103L void shrink_to_fit() - { _M_shrink_to_fit(); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("shrink_to_fit() on corrupt (dangling?) vector"); +#endif + _M_shrink_to_fit(); + } #endif void flip() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("flip() on corrupt (dangling?) vector"); +#endif for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != this->_M_impl._M_end_of_storage; ++__p) *__p = ~*__p; diff --git a/gcc-4.9/libstdc++-v3/include/bits/stl_deque.h b/gcc-4.9/libstdc++-v3/include/bits/stl_deque.h index add8742a1..40ff8d692 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/stl_deque.h +++ b/gcc-4.9/libstdc++-v3/include/bits/stl_deque.h @@ -1247,7 +1247,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ reference operator[](size_type __n) _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start[difference_type(__n)]; } + { +#if __google_stl_debug_deque + _M_range_check(__n); +#endif + return this->_M_impl._M_start[difference_type(__n)]; + } /** * @brief Subscript access to the data contained in the %deque. @@ -1262,7 +1267,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ const_reference operator[](size_type __n) const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start[difference_type(__n)]; } + { +#if __google_stl_debug_deque + _M_range_check(__n); +#endif + return this->_M_impl._M_start[difference_type(__n)]; + } protected: /// Safety check used only from at(). @@ -1319,7 +1329,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ reference front() _GLIBCXX_NOEXCEPT - { return *begin(); } + { +#if __google_stl_debug_deque + if (empty()) __throw_logic_error("front() on empty deque"); +#endif + return *begin(); + } /** * Returns a read-only (constant) reference to the data at the first @@ -1327,7 +1342,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ const_reference front() const _GLIBCXX_NOEXCEPT - { return *begin(); } + { +#if __google_stl_debug_deque + if (empty()) __throw_logic_error("front() on empty deque"); +#endif + return *begin(); + } /** * Returns a read/write reference to the data at the last element of the @@ -1336,6 +1356,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER reference back() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_deque + if (empty()) __throw_logic_error("back() on empty deque"); +#endif iterator __tmp = end(); --__tmp; return *__tmp; @@ -1348,6 +1371,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const_reference back() const _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_deque + if (empty()) __throw_logic_error("back() on empty deque"); +#endif const_iterator __tmp = end(); --__tmp; return *__tmp; @@ -1428,6 +1454,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void pop_front() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_deque + if (empty()) __throw_logic_error("pop_front() on empty deque"); +#endif if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_last - 1) { @@ -1449,6 +1478,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void pop_back() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_deque + if (empty()) __throw_logic_error("pop_back() on empty deque"); +#endif if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first) { @@ -1540,6 +1572,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER iterator insert(const_iterator __position, size_type __n, const value_type& __x) { +#if __google_stl_debug_deque + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif difference_type __offset = __position - cbegin(); _M_fill_insert(__position._M_const_cast(), __n, __x); return begin() + __offset; @@ -1556,7 +1592,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ void insert(iterator __position, size_type __n, const value_type& __x) - { _M_fill_insert(__position, __n, __x); } + { +#if __google_stl_debug_deque + if (__position < this->begin() || __position > this->end()) + __throw_logic_error("insert() at invalid position"); +#endif + _M_fill_insert(__position, __n, __x); + } #endif #if __cplusplus >= 201103L @@ -1577,6 +1619,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif difference_type __offset = __position - cbegin(); _M_insert_dispatch(__position._M_const_cast(), __first, __last, __false_type()); diff --git a/gcc-4.9/libstdc++-v3/include/bits/stl_tree.h b/gcc-4.9/libstdc++-v3/include/bits/stl_tree.h index cac917ea3..61156dbf7 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/stl_tree.h +++ b/gcc-4.9/libstdc++-v3/include/bits/stl_tree.h @@ -486,7 +486,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + // Local modification: if __google_stl_debug_rbtree is defined to + // non-zero value, check sort predicate for strict weak ordering. + // Google ref b/1731200. +#if __google_stl_debug_rbtree + template<typename _KeyCompare> + struct _CheckedCompare { + _KeyCompare _M_key_compare; + + _CheckedCompare(): _M_key_compare() { } + _CheckedCompare(const _KeyCompare & __comp): _M_key_compare(__comp) { } + + // Template arg required to avoid duplicating code in the two op() + // operators below. User-provided _M_key_compare may not be const, + // but needs to be callable from our const op(). + // Google ref. b/1731200. + template <typename _KeyCompareT> + static bool _M_compare_with(_KeyCompareT& __comp, const _Key& __x, const _Key& __y) { + if (__comp(__x, __x)) + __throw_runtime_error("strict weak ordering: (__x LT __x) != false"); + if (__comp(__y, __y)) + __throw_runtime_error("strict weak ordering: (__y LT __y) != false"); + bool lt = __comp(__x, __y); + if (lt && __comp(__y, __x)) + __throw_runtime_error("strict weak ordering: ((__x LT __y) && (__y LT __x)) != false"); + return lt; + } + bool operator()(const _Key& __x, const _Key& __y) const { + return _M_compare_with(_M_key_compare, __x, __y); + } + + bool operator()(const _Key& __x, const _Key& __y) { + return _M_compare_with(_M_key_compare, __x, __y); + } + + operator _KeyCompare() const { return _M_key_compare; } + }; + + _Rb_tree_impl<_CheckedCompare<_Compare> > _M_impl; +#else _Rb_tree_impl<_Compare> _M_impl; +#endif protected: _Base_ptr& @@ -526,11 +566,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Link_type _M_end() _GLIBCXX_NOEXCEPT - { return static_cast<_Link_type>(&this->_M_impl._M_header); } + { return reinterpret_cast<_Link_type>(&this->_M_impl._M_header); } _Const_Link_type _M_end() const _GLIBCXX_NOEXCEPT - { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } + { return reinterpret_cast<_Const_Link_type>(&this->_M_impl._M_header); } static const_reference _S_value(_Const_Link_type __x) diff --git a/gcc-4.9/libstdc++-v3/include/bits/stl_vector.h b/gcc-4.9/libstdc++-v3/include/bits/stl_vector.h index c33e2c6ae..f7c735993 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/stl_vector.h +++ b/gcc-4.9/libstdc++-v3/include/bits/stl_vector.h @@ -63,6 +63,20 @@ #include <initializer_list> #endif +#ifdef _GLIBCXX_ADDRESS_SANITIZER_ANNOTATIONS +extern "C" void +__sanitizer_annotate_contiguous_container(const void *, const void *, + const void *, const void *); +#else +// When sanitizer annotataions are off, avoid bazillion of no-op +// functions that blow up debug binary size. +#define __sanitizer_vector_annotate_new() +#define __sanitizer_vector_annotate_delete() +#define __sanitizer_vector_annotate_increase(a) +#define __sanitizer_vector_annotate_shrink(a) +#endif // _GLIBCXX_ADDRESS_SANITIZER_ANNOTATIONS + + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_CONTAINER @@ -158,7 +172,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER ~_Vector_base() _GLIBCXX_NOEXCEPT { _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage - - this->_M_impl._M_start); } + - this->_M_impl._M_start); +#if __google_stl_debug_dangling_vector + this->_M_impl._M_start = 0; + this->_M_impl._M_finish = reinterpret_cast<_Tp*>(~0UL); +#endif + } public: _Vector_impl _M_impl; @@ -243,6 +262,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER using _Base::_M_impl; using _Base::_M_get_Tp_allocator; + bool _M_is_valid() const + { + if (this->_M_impl._M_end_of_storage == 0 + && this->_M_impl._M_start == 0 + && this->_M_impl._M_finish == 0) + return true; + + if (this->_M_impl._M_start <= this->_M_impl._M_finish + && this->_M_impl._M_finish <= this->_M_impl._M_end_of_storage) + { + if (this->_M_impl._M_start < this->_M_impl._M_end_of_storage) + return true; + else if (this->_M_impl._M_start == this->_M_impl._M_end_of_storage + && this->_M_impl._M_start == this->_M_impl._M_finish) + { + pointer _0xcdcd; + + __builtin_memset(&_0xcdcd, 0xcd, sizeof(_0xcdcd)); + return this->_M_impl._M_finish != _0xcdcd; + } + } + + return false; + } + public: // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) @@ -545,7 +589,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ iterator begin() _GLIBCXX_NOEXCEPT - { return iterator(this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return iterator(this->_M_impl._M_start); + } /** * Returns a read-only (constant) iterator that points to the @@ -554,7 +604,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ const_iterator begin() const _GLIBCXX_NOEXCEPT - { return const_iterator(this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return const_iterator(this->_M_impl._M_start); + } /** * Returns a read/write iterator that points one past the last @@ -563,7 +619,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ iterator end() _GLIBCXX_NOEXCEPT - { return iterator(this->_M_impl._M_finish); } + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return iterator(this->_M_impl._M_finish); + } /** * Returns a read-only (constant) iterator that points one past @@ -572,7 +634,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ const_iterator end() const _GLIBCXX_NOEXCEPT - { return const_iterator(this->_M_impl._M_finish); } + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return const_iterator(this->_M_impl._M_finish); + } /** * Returns a read/write reverse iterator that points to the @@ -652,7 +720,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** Returns the number of elements in the %vector. */ size_type size() const _GLIBCXX_NOEXCEPT - { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("size() on corrupt (dangling?) vector"); +#endif + return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); + } /** Returns the size() of the largest possible %vector. */ size_type @@ -732,7 +806,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ size_type capacity() const _GLIBCXX_NOEXCEPT - { return size_type(this->_M_impl._M_end_of_storage + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("capacity() on corrupt (dangling?) vector"); +#endif + return size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } /** @@ -774,10 +853,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) + * + * Local modification: range checks are performed if + * __google_stl_debug_vector is defined to non-zero. */ reference operator[](size_type __n) _GLIBCXX_NOEXCEPT - { return *(this->_M_impl._M_start + __n); } + { +#if __google_stl_debug_vector + _M_range_check(__n); +#endif + return *(this->_M_impl._M_start + __n); + } /** * @brief Subscript access to the data contained in the %vector. @@ -789,10 +876,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * Note that data access with this operator is unchecked and * out_of_range lookups are not defined. (For checked lookups * see at().) + * + * Local modification: range checks are performed if + * __google_stl_debug_vector is defined to non-zero. */ const_reference operator[](size_type __n) const _GLIBCXX_NOEXCEPT - { return *(this->_M_impl._M_start + __n); } + { +#if __google_stl_debug_vector + _M_range_check(__n); +#endif + return *(this->_M_impl._M_start + __n); + } protected: /// Safety check used only from at(). @@ -849,7 +944,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ reference front() _GLIBCXX_NOEXCEPT - { return *begin(); } + { +#if __google_stl_debug_vector + if (empty()) __throw_logic_error("front() on empty vector"); +#endif + return *begin(); + } /** * Returns a read-only (constant) reference to the data at the first @@ -857,7 +957,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ const_reference front() const _GLIBCXX_NOEXCEPT - { return *begin(); } + { +#if __google_stl_debug_vector + if (empty()) __throw_logic_error("front() on empty vector"); +#endif + return *begin(); + } /** * Returns a read/write reference to the data at the last @@ -865,7 +970,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ reference back() _GLIBCXX_NOEXCEPT - { return *(end() - 1); } + { +#if __google_stl_debug_vector + if (empty()) __throw_logic_error("back() on empty vector"); +#endif + return *(end() - 1); + } /** * Returns a read-only (constant) reference to the data at the @@ -873,7 +983,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ const_reference back() const _GLIBCXX_NOEXCEPT - { return *(end() - 1); } + { +#if __google_stl_debug_vector + if (empty()) __throw_logic_error("back() on empty vector"); +#endif + return *(end() - 1); + } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. @@ -888,7 +1003,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer #endif data() _GLIBCXX_NOEXCEPT - { return _M_data_ptr(this->_M_impl._M_start); } + { +#if __google_stl_debug_vector + if (empty()) return 0; +#endif + return _M_data_ptr(this->_M_impl._M_start); + } #if __cplusplus >= 201103L const _Tp* @@ -896,7 +1016,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const_pointer #endif data() const _GLIBCXX_NOEXCEPT - { return _M_data_ptr(this->_M_impl._M_start); } + { +#if __google_stl_debug_vector + if (empty()) return 0; +#endif + return _M_data_ptr(this->_M_impl._M_start); + } // [23.2.4.3] modifiers /** @@ -914,6 +1039,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { + __sanitizer_vector_annotate_increase(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; @@ -948,8 +1074,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void pop_back() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_vector + if (this->empty()) + __throw_logic_error(__N("pop_back() on empty vector")); +#endif + size_type __old_size = size(); --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + __sanitizer_vector_annotate_shrink(__old_size); } #if __cplusplus >= 201103L @@ -1050,6 +1182,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER iterator insert(const_iterator __position, size_type __n, const value_type& __x) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif difference_type __offset = __position - cbegin(); _M_fill_insert(begin() + __offset, __n, __x); return begin() + __offset; @@ -1070,7 +1206,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ void insert(iterator __position, size_type __n, const value_type& __x) - { _M_fill_insert(__position, __n, __x); } + { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif + _M_fill_insert(__position, __n, __x); + } #endif #if __cplusplus >= 201103L @@ -1095,6 +1237,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif difference_type __offset = __position - cbegin(); _M_insert_dispatch(begin() + __offset, __first, __last, __false_type()); @@ -1120,6 +1266,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif // Check whether it's an integral type. If so, it's not an iterator. typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); @@ -1196,6 +1346,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER noexcept(_Alloc_traits::_S_nothrow_swap()) #endif { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid() || !__x._M_is_valid()) + __throw_logic_error("swap() on corrupt (dangling?) vector"); +#endif this->_M_impl._M_swap_data(__x._M_impl); _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); @@ -1209,7 +1363,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ void clear() _GLIBCXX_NOEXCEPT - { _M_erase_at_end(this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid()) + __throw_logic_error("clear() on corrupt (dangling?) vector"); +#endif + _M_erase_at_end(this->_M_impl._M_start); + } protected: /** @@ -1435,8 +1595,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void _M_erase_at_end(pointer __pos) _GLIBCXX_NOEXCEPT { + size_type __old_size = size(); std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); this->_M_impl._M_finish = __pos; + __sanitizer_vector_annotate_shrink(__old_size); } iterator @@ -1493,6 +1655,72 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_data_ptr(_Ptr __ptr) const { return __ptr; } #endif + +#ifdef _GLIBCXX_ADDRESS_SANITIZER_ANNOTATIONS + private: + template<class T, class U> + struct __is_same_allocator { + static void __annotate_contiguous_container(pointer __beg, + pointer __end, + pointer __old_mid, + pointer __new_mid) { } + }; + // The following functions are no-ops outside of AddressSanitizer mode. + // We call annotatations only for the default Allocator because + // other allocators may not meet the AddressSanitizer alignment + // constraints. + // See the documentation for __sanitizer_annotate_contiguous_container + // for more details. + template <class T> struct __is_same_allocator<T, T> { + static void __annotate_contiguous_container(pointer __beg, + pointer __end, + pointer __old_mid, + pointer __new_mid) { + if (__beg) + __sanitizer_annotate_contiguous_container(__beg, + __end, + __old_mid, + __new_mid); + } + }; + + void __annotate_contiguous_container(pointer __beg, + pointer __end, + pointer __old_mid, + pointer __new_mid) + { + __is_same_allocator<_Alloc, std::allocator<_Tp> >:: + __annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); + } + void __sanitizer_vector_annotate_new() + { + __annotate_contiguous_container(_M_impl._M_start, + _M_impl._M_end_of_storage, + _M_impl._M_end_of_storage, + _M_impl._M_finish); + } + void __sanitizer_vector_annotate_delete() + { + __annotate_contiguous_container(_M_impl._M_start, + _M_impl._M_end_of_storage, + _M_impl._M_finish, + _M_impl._M_end_of_storage); + } + void __sanitizer_vector_annotate_increase(size_type __n) + { + __annotate_contiguous_container(_M_impl._M_start, + _M_impl._M_end_of_storage, + _M_impl._M_finish, + _M_impl._M_finish + __n); + } + void __sanitizer_vector_annotate_shrink(size_type __old_size) + { + __annotate_contiguous_container(_M_impl._M_start, + _M_impl._M_end_of_storage, + _M_impl._M_start + __old_size, + _M_impl._M_finish); + } +#endif // _GLIBCXX_ADDRESS_SANITIZER_ANNOTATIONS }; diff --git a/gcc-4.9/libstdc++-v3/include/bits/vector.tcc b/gcc-4.9/libstdc++-v3/include/bits/vector.tcc index c937b3887..015ccd60a 100644 --- a/gcc-4.9/libstdc++-v3/include/bits/vector.tcc +++ b/gcc-4.9/libstdc++-v3/include/bits/vector.tcc @@ -73,6 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer __tmp = _M_allocate_and_copy(__n, _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -81,6 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __tmp; this->_M_impl._M_finish = __tmp + __old_size; this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + __sanitizer_vector_annotate_new(); } } @@ -93,6 +95,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { + __sanitizer_vector_annotate_increase(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; @@ -111,10 +114,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER insert(iterator __position, const value_type& __x) #endif { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("insert() at invalid position")); +#endif const size_type __n = __position - begin(); if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) { + __sanitizer_vector_annotate_increase(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); ++this->_M_impl._M_finish; } @@ -141,10 +149,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector<_Tp, _Alloc>:: _M_erase(iterator __position) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position >= this->end()) + __throw_out_of_range(__N("erase() at invalid position")); +#endif if (__position + 1 != end()) _GLIBCXX_MOVE3(__position + 1, end(), __position); --this->_M_impl._M_finish; _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); + __sanitizer_vector_annotate_shrink(size() + 1); return __position; } @@ -153,6 +166,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector<_Tp, _Alloc>:: _M_erase(iterator __first, iterator __last) { +#if __google_stl_debug_vector + if (__first < this->begin() || __first > __last || __last > this->end()) + __throw_out_of_range("erase() invalid range"); +#endif if (__first != __last) { if (__last != end()) @@ -167,8 +184,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector<_Tp, _Alloc>:: operator=(const vector<_Tp, _Alloc>& __x) { +#if __google_stl_debug_dangling_vector + if (!this->_M_is_valid() || !__x._M_is_valid()) + __throw_logic_error("operator=() on corrupt (dangling?) vector"); +#endif if (&__x != this) { + __sanitizer_vector_annotate_delete(); #if __cplusplus >= 201103L if (_Alloc_traits::_S_propagate_on_copy_assign()) { @@ -216,6 +238,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_get_Tp_allocator()); } this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; + __sanitizer_vector_annotate_new(); } return *this; } @@ -227,11 +250,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (__n > capacity()) { + __sanitizer_vector_annotate_delete(); vector __tmp(__n, __val, _M_get_Tp_allocator()); __tmp.swap(*this); } else if (__n > size()) { + __sanitizer_vector_annotate_increase(__n - size()); std::fill(begin(), end(), __val); std::__uninitialized_fill_n_a(this->_M_impl._M_finish, __n - size(), __val, @@ -271,6 +296,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (__len > capacity()) { pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -279,11 +305,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __tmp; this->_M_impl._M_finish = this->_M_impl._M_start + __len; this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; + __sanitizer_vector_annotate_new(); } else if (size() >= __len) _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); else { + __sanitizer_vector_annotate_increase(__len - size()); _ForwardIterator __mid = __first; std::advance(__mid, size()); std::copy(__first, __mid, this->_M_impl._M_start); @@ -301,10 +329,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector<_Tp, _Alloc>:: emplace(const_iterator __position, _Args&&... __args) { +#if __google_stl_debug_vector + if (__position < this->begin() || __position > this->end()) + __throw_out_of_range(__N("emplace() at invalid position")); +#endif const size_type __n = __position - begin(); if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage && __position == end()) { + __sanitizer_vector_annotate_increase(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, std::forward<_Args>(__args)...); ++this->_M_impl._M_finish; @@ -329,6 +362,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) { + __sanitizer_vector_annotate_increase(1); _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, _GLIBCXX_MOVE(*(this->_M_impl._M_finish - 1))); @@ -389,6 +423,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -397,6 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; + __sanitizer_vector_annotate_new(); } } @@ -433,6 +469,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -441,6 +478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; + __sanitizer_vector_annotate_new(); } #endif @@ -454,6 +492,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { + __sanitizer_vector_annotate_increase(__n); value_type __x_copy = __x; const size_type __elems_after = end() - __position; pointer __old_finish(this->_M_impl._M_finish); @@ -522,6 +561,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -530,6 +570,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; + __sanitizer_vector_annotate_new(); } } } @@ -545,6 +586,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { + __sanitizer_vector_annotate_increase(__n); std::__uninitialized_default_n_a(this->_M_impl._M_finish, __n, _M_get_Tp_allocator()); this->_M_impl._M_finish += __n; @@ -573,6 +615,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -581,6 +624,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; + __sanitizer_vector_annotate_new(); } } } @@ -592,7 +636,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { if (capacity() == size()) return false; - return std::__shrink_to_fit_aux<vector>::_S_do_it(*this); + __sanitizer_vector_annotate_delete(); + bool __res = std::__shrink_to_fit_aux<vector>::_S_do_it(*this); + __sanitizer_vector_annotate_new(); + return __res; } #endif @@ -623,6 +670,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER if (size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_finish) >= __n) { + __sanitizer_vector_annotate_increase(__n); const size_type __elems_after = end() - __position; pointer __old_finish(this->_M_impl._M_finish); if (__elems_after > __n) @@ -680,6 +728,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _M_deallocate(__new_start, __len); __throw_exception_again; } + __sanitizer_vector_annotate_delete(); std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, _M_get_Tp_allocator()); _M_deallocate(this->_M_impl._M_start, @@ -688,6 +737,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_start = __new_start; this->_M_impl._M_finish = __new_finish; this->_M_impl._M_end_of_storage = __new_start + __len; + __sanitizer_vector_annotate_new(); } } } diff --git a/gcc-4.9/libstdc++-v3/include/ext/new_allocator.h b/gcc-4.9/libstdc++-v3/include/ext/new_allocator.h index 996a2195e..ee9333e1f 100644 --- a/gcc-4.9/libstdc++-v3/include/ext/new_allocator.h +++ b/gcc-4.9/libstdc++-v3/include/ext/new_allocator.h @@ -104,10 +104,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); } +#ifdef __GXX_DELETE_WITH_SIZE__ + // __p is not permitted to be a null pointer. + void + deallocate(pointer __p, size_type __t) + { ::operator delete(__p, __t * sizeof(_Tp)); } +#else // __p is not permitted to be a null pointer. void deallocate(pointer __p, size_type) { ::operator delete(__p); } +#endif size_type max_size() const _GLIBCXX_USE_NOEXCEPT diff --git a/gcc-4.9/libstdc++-v3/include/ext/sso_string_base.h b/gcc-4.9/libstdc++-v3/include/ext/sso_string_base.h index 80c88aeb5..3ad4e9547 100644 --- a/gcc-4.9/libstdc++-v3/include/ext/sso_string_base.h +++ b/gcc-4.9/libstdc++-v3/include/ext/sso_string_base.h @@ -85,6 +85,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (!_M_is_local()) _M_destroy(_M_allocated_capacity); +#if __google_stl_debug_dangling_string + else { + // Wipe local storage for destructed string with 0xCD. + // This mimics what DebugAllocation does to free()d memory. + __builtin_memset(_M_local_data, 0xcd, sizeof(_M_local_data)); + } +#endif } void @@ -168,15 +175,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_leak() { } void - _M_set_length(size_type __n) + _M_set_length_no_wipe(size_type __n) { _M_length(__n); traits_type::assign(_M_data()[__n], _CharT()); } + void + _M_set_length(size_type __n) + { +#if __google_stl_debug_dangling_string + if (__n + 1 < _M_length()) + { + // Wipe the storage with 0xCD. + // Also wipes the old NUL terminator. + __builtin_memset(_M_data() + __n + 1, 0xcd, _M_length() - __n); + } +#endif + _M_set_length_no_wipe(__n); + } + __sso_string_base() : _M_dataplus(_M_local_data) - { _M_set_length(0); } + { _M_set_length_no_wipe(0); } __sso_string_base(const _Alloc& __a); @@ -193,7 +214,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _Alloc& __a); ~__sso_string_base() - { _M_dispose(); } + { + _M_dispose(); +#ifdef __google_stl_debug_dangling_string + __builtin_memset(this, 0xcd, sizeof(*this)); +#endif + } _CharT_alloc_type& _M_get_allocator() @@ -335,7 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(const _Alloc& __a) : _M_dataplus(__a, _M_local_data) - { _M_set_length(0); } + { _M_set_length_no_wipe(0); } template<typename _CharT, typename _Traits, typename _Alloc> __sso_string_base<_CharT, _Traits, _Alloc>:: @@ -361,9 +387,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_capacity(__rcs._M_allocated_capacity); } - _M_set_length(__rcs._M_length()); + _M_set_length_no_wipe(__rcs._M_length()); __rcs._M_data(__rcs._M_local_data); - __rcs._M_set_length(0); + __rcs._M_set_length_no_wipe(0); } #endif @@ -425,7 +451,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_exception_again; } - _M_set_length(__len); + _M_set_length_no_wipe(__len); } template<typename _CharT, typename _Traits, typename _Alloc> @@ -457,7 +483,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_exception_again; } - _M_set_length(__dnew); + _M_set_length_no_wipe(__dnew); } template<typename _CharT, typename _Traits, typename _Alloc> @@ -474,7 +500,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__n) this->_S_assign(_M_data(), __n, __c); - _M_set_length(__n); + _M_set_length_no_wipe(__n); } template<typename _CharT, typename _Traits, typename _Alloc> diff --git a/gcc-4.9/libstdc++-v3/include/ext/vstring.h b/gcc-4.9/libstdc++-v3/include/ext/vstring.h index 749d370f9..45d807961 100644 --- a/gcc-4.9/libstdc++-v3/include/ext/vstring.h +++ b/gcc-4.9/libstdc++-v3/include/ext/vstring.h @@ -39,6 +39,21 @@ #include <ext/rc_string_base.h> #include <ext/sso_string_base.h> +#if __google_stl_debug_string && !defined(_GLIBCXX_DEBUG) +# undef _GLIBCXX_DEBUG_ASSERT +# undef _GLIBCXX_DEBUG_PEDASSERT +// Perform additional checks (but only in this file). +# define _GLIBCXX_DEBUG_ASSERT(_Condition) \ + if (! (_Condition)) { \ + char buf[512]; \ + __builtin_snprintf(buf, sizeof(buf), \ + "%s:%d: %s: Assertion '%s' failed.\n", \ + __FILE__, __LINE__, __func__, # _Condition); \ + std::__throw_runtime_error(buf); \ + } +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ASSERT(_Condition) +#endif + namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -536,7 +551,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const_reference operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_string && !defined(_GLIBCXX_DEBUG) + if (__pos > this->size()) + std::__throw_out_of_range_fmt(__N("__versa_string::operator[]: __pos " + "(which is %zu) > this->size() " + "(which is %zu)"), + __pos, this->size()); +#else _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); +#endif return this->_M_data()[__pos]; } @@ -555,7 +578,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // Allow pos == size() both in C++98 mode, as v3 extension, // and in C++11 mode. +#if __google_stl_debug_string && !defined(_GLIBCXX_DEBUG) + if (__pos > this->size()) + std::__throw_out_of_range_fmt(__N("__versa_string::operator[]: __pos " + "(which is %zu) > this->size() " + "(which is %zu)"), + __pos, this->size()); +#else _GLIBCXX_DEBUG_ASSERT(__pos <= this->size()); +#endif // In pedantic mode be strict in C++98 mode. _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < this->size()); @@ -2960,4 +2991,12 @@ _GLIBCXX_END_NAMESPACE_VERSION #include "vstring.tcc" +#if __google_stl_debug_string && !defined(_GLIBCXX_DEBUG) +// Undo our defines, so they don't affect anything else. +# undef _GLIBCXX_DEBUG_ASSERT +# undef _GLIBCXX_DEBUG_PEDASSERT +# define _GLIBCXX_DEBUG_ASSERT(_Condition) +# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) +#endif + #endif /* _VSTRING_H */ diff --git a/gcc-4.9/libstdc++-v3/include/std/future b/gcc-4.9/libstdc++-v3/include/std/future index 717ce7105..998e90a98 100644 --- a/gcc-4.9/libstdc++-v3/include/std/future +++ b/gcc-4.9/libstdc++-v3/include/std/future @@ -365,12 +365,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) { - bool __set = __ignore_failure; + bool __set = false; // all calls to this function are serialized, // side-effects of invoking __res only happen once call_once(_M_once, &_State_baseV2::_M_do_set, this, ref(__res), ref(__set)); - if (!__set) + if (__set) + _M_cond.notify_all(); + else if (!__ignore_failure) __throw_future_error(int(future_errc::promise_already_satisfied)); } @@ -485,7 +487,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION lock_guard<mutex> __lock(_M_mutex); _M_result.swap(__res); } - _M_cond.notify_all(); __set = true; } @@ -495,6 +496,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual void _M_complete_async() { } // Return true if state contains a deferred function. + // Caller must own _M_mutex. virtual bool _M_has_deferred() const { return false; } }; @@ -1007,22 +1009,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void set_value(const _Res& __r) { + auto __future = _M_future; auto __setter = _State::__setter(this, __r); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } void set_value(_Res&& __r) { + auto __future = _M_future; auto __setter = _State::__setter(this, std::move(__r)); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } void set_exception(exception_ptr __p) { + auto __future = _M_future; auto __setter = _State::__setter(__p, this); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } }; @@ -1105,15 +1110,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void set_value(_Res& __r) { + auto __future = _M_future; auto __setter = _State::__setter(this, __r); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } void set_exception(exception_ptr __p) { + auto __future = _M_future; auto __setter = _State::__setter(__p, this); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } }; @@ -1190,8 +1197,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void set_exception(exception_ptr __p) { + auto __future = _M_future; auto __setter = _State::__setter(__p, this); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } }; @@ -1217,8 +1225,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline void promise<void>::set_value() { + auto __future = _M_future; auto __setter = _State::__setter(this); - _M_future->_M_set_result(std::move(__setter)); + __future->_M_set_result(std::move(__setter)); } diff --git a/gcc-4.9/libstdc++-v3/include/std/iomanip b/gcc-4.9/libstdc++-v3/include/std/iomanip index 73822db9b..cc6f60cde 100644 --- a/gcc-4.9/libstdc++-v3/include/std/iomanip +++ b/gcc-4.9/libstdc++-v3/include/std/iomanip @@ -41,6 +41,9 @@ #if __cplusplus >= 201103L #include <locale> +#if __cplusplus > 201103L +#include <sstream> // used in quoted. +#endif #endif namespace std _GLIBCXX_VISIBILITY(default) @@ -342,7 +345,6 @@ _GLIBCXX_END_NAMESPACE_VERSION /** * @brief Struct for delimited strings. - * The left and right delimiters can be different. */ template<typename _String, typename _CharT> struct _Quoted_string @@ -364,45 +366,51 @@ _GLIBCXX_END_NAMESPACE_VERSION }; /** - * @brief Inserter for delimited strings. - * The left and right delimiters can be different. + * @brief Inserter for quoted strings. + * + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 2344 quoted()'s interaction with padding is unclear */ template<typename _CharT, typename _Traits> auto& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Quoted_string<const _CharT*, _CharT>& __str) { - __os << __str._M_delim; + std::basic_ostringstream<_CharT, _Traits> __ostr; + __ostr << __str._M_delim; for (const _CharT* __c = __str._M_string; *__c; ++__c) { if (*__c == __str._M_delim || *__c == __str._M_escape) - __os << __str._M_escape; - __os << *__c; + __ostr << __str._M_escape; + __ostr << *__c; } - __os << __str._M_delim; + __ostr << __str._M_delim; - return __os; + return __os << __ostr.str(); } /** - * @brief Inserter for delimited strings. - * The left and right delimiters can be different. + * @brief Inserter for quoted strings. + * + * _GLIBCXX_RESOLVE_LIB_DEFECTS + * DR 2344 quoted()'s interaction with padding is unclear */ template<typename _CharT, typename _Traits, typename _String> auto& operator<<(std::basic_ostream<_CharT, _Traits>& __os, const _Quoted_string<_String, _CharT>& __str) { - __os << __str._M_delim; + std::basic_ostringstream<_CharT, _Traits> __ostr; + __ostr << __str._M_delim; for (auto& __c : __str._M_string) { if (__c == __str._M_delim || __c == __str._M_escape) - __os << __str._M_escape; - __os << __c; + __ostr << __str._M_escape; + __ostr << __c; } - __os << __str._M_delim; + __ostr << __str._M_delim; - return __os; + return __os << __ostr.str(); } /** diff --git a/gcc-4.9/libstdc++-v3/include/std/tuple b/gcc-4.9/libstdc++-v3/include/std/tuple index 03d87d77a..103c99e06 100644 --- a/gcc-4.9/libstdc++-v3/include/std/tuple +++ b/gcc-4.9/libstdc++-v3/include/std/tuple @@ -719,23 +719,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> struct tuple_size; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2313. tuple_size should always derive from integral_constant<size_t, N> template<typename _Tp> struct tuple_size<const _Tp> - : public integral_constant< - typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, - tuple_size<_Tp>::value> { }; + : public integral_constant<size_t, tuple_size<_Tp>::value> { }; template<typename _Tp> struct tuple_size<volatile _Tp> - : public integral_constant< - typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, - tuple_size<_Tp>::value> { }; + : public integral_constant<size_t, tuple_size<_Tp>::value> { }; template<typename _Tp> struct tuple_size<const volatile _Tp> - : public integral_constant< - typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, - tuple_size<_Tp>::value> { }; + : public integral_constant<size_t, tuple_size<_Tp>::value> { }; /// class tuple_size template<typename... _Elements> @@ -752,9 +748,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } - // Return a reference (const reference, rvalue reference) to the ith element - // of a tuple. Any const or non-const ref elements are returned with their - // original type. + /// Return a reference to the ith element of a tuple. template<std::size_t __i, typename... _Elements> constexpr typename __add_ref< typename tuple_element<__i, tuple<_Elements...>>::type @@ -762,6 +756,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get(tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } + /// Return a const reference to the ith element of a const tuple. template<std::size_t __i, typename... _Elements> constexpr typename __add_c_ref< typename tuple_element<__i, tuple<_Elements...>>::type @@ -769,6 +764,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION get(const tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); } + /// Return an rvalue reference to the ith element of a tuple rvalue. template<std::size_t __i, typename... _Elements> constexpr typename __add_r_ref< typename tuple_element<__i, tuple<_Elements...>>::type @@ -788,22 +784,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } + /// Return a reference to the unique element of type _Tp of a tuple. template <typename _Tp, typename... _Types> constexpr _Tp& get(tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } + /// Return a reference to the unique element of type _Tp of a tuple rvalue. template <typename _Tp, typename... _Types> constexpr _Tp&& get(tuple<_Types...>&& __t) noexcept - { return std::move(std::__get_helper2<_Tp>(__t)); } + { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } + /// Return a const reference to the unique element of type _Tp of a tuple. template <typename _Tp, typename... _Types> constexpr const _Tp& get(const tuple<_Types...>& __t) noexcept { return std::__get_helper2<_Tp>(__t); } #endif + // This class helps construct the various comparison operations on tuples template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, typename _Tp, typename _Up> diff --git a/gcc-4.9/libstdc++-v3/include/std/type_traits b/gcc-4.9/libstdc++-v3/include/std/type_traits index 86fde9e0c..9a5c06e9c 100644 --- a/gcc-4.9/libstdc++-v3/include/std/type_traits +++ b/gcc-4.9/libstdc++-v3/include/std/type_traits @@ -37,6 +37,18 @@ #include <bits/c++config.h> +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +# if defined (__UINT_LEAST16_TYPE__) && defined(__UINT_LEAST32_TYPE__) +namespace std +{ + typedef __UINT_LEAST16_TYPE__ uint_least16_t; + typedef __UINT_LEAST32_TYPE__ uint_least32_t; +} +# else +# include <cstdint> +# endif +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -259,7 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_floating_point_helper<long double> : public true_type { }; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) && (!defined(__clang__) || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) +#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) && (!defined (__ANDROID__) || !defined(__clang__) || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4)) template<> struct __is_floating_point_helper<__float128> : public true_type { }; @@ -1583,6 +1595,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_unsigned<long long> { typedef unsigned long long __type; }; +#if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__) + template<> + struct __make_unsigned<wchar_t> : __make_unsigned<__WCHAR_TYPE__> + { }; +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) template<> struct __make_unsigned<__int128> @@ -1665,6 +1683,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __make_signed<unsigned long long> { typedef signed long long __type; }; +#if defined(_GLIBCXX_USE_WCHAR_T) && defined(__WCHAR_UNSIGNED__) + template<> + struct __make_signed<wchar_t> : __make_signed<__WCHAR_TYPE__> + { }; +#endif + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + template<> + struct __make_signed<char16_t> : __make_signed<uint_least16_t> + { }; + template<> + struct __make_signed<char32_t> : __make_signed<uint_least32_t> + { }; +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) template<> struct __make_signed<unsigned __int128> @@ -1938,7 +1971,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __common_type_impl : private __do_common_type_impl { +#if !defined (__ANDROID__) + typedef decltype(_S_test<_Tp, _Up>(0)) type; +#else typedef typename decay<decltype(_S_test<_Tp, _Up>(0))>::type type; +#endif }; struct __do_member_type_wrapper diff --git a/gcc-4.9/libstdc++-v3/include/tr2/bool_set b/gcc-4.9/libstdc++-v3/include/tr2/bool_set index d97714c11..34e58f4a9 100644 --- a/gcc-4.9/libstdc++-v3/include/tr2/bool_set +++ b/gcc-4.9/libstdc++-v3/include/tr2/bool_set @@ -44,7 +44,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * bool_set * * See N2136, Bool_set: multi-valued logic - * by Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion. + * by HervĂ© Brönnimann, Guillaume Melquiond, Sylvain Pion. * * The implicit conversion to bool is slippery! I may use the new * explicit conversion. This has been specialized in the language |