aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libstdc++-v3/include
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/libstdc++-v3/include')
-rw-r--r--gcc-4.9/libstdc++-v3/include/Makefile.am1
-rw-r--r--gcc-4.9/libstdc++-v3/include/Makefile.in1
-rw-r--r--gcc-4.9/libstdc++-v3/include/backward/hashtable.h3
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/deque.tcc16
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/hashtable.h146
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/regex_automaton.tcc18
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/regex_compiler.h11
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/regex_compiler.tcc17
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/regex_executor.tcc6
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/stl_algo.h80
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/stl_bvector.h245
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/stl_deque.h56
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/stl_tree.h44
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/stl_vector.h262
-rw-r--r--gcc-4.9/libstdc++-v3/include/bits/vector.tcc52
-rw-r--r--gcc-4.9/libstdc++-v3/include/ext/new_allocator.h7
-rw-r--r--gcc-4.9/libstdc++-v3/include/ext/sso_string_base.h44
-rw-r--r--gcc-4.9/libstdc++-v3/include/ext/vstring.h39
-rw-r--r--gcc-4.9/libstdc++-v3/include/std/future29
-rw-r--r--gcc-4.9/libstdc++-v3/include/std/iomanip38
-rw-r--r--gcc-4.9/libstdc++-v3/include/std/tuple26
-rw-r--r--gcc-4.9/libstdc++-v3/include/std/type_traits39
-rw-r--r--gcc-4.9/libstdc++-v3/include/tr2/bool_set2
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