]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Print additional info when various out-of-range conditions are detected.
authorPaul Pluzhnikov <ppluzhnikov@google.com>
Sun, 22 Sep 2013 02:04:13 +0000 (19:04 -0700)
committerPaul Pluzhnikov <ppluzhnikov@gcc.gnu.org>
Sun, 22 Sep 2013 02:04:13 +0000 (19:04 -0700)
2013-09-21  Paul Pluzhnikov  <ppluzhnikov@google.com>

* include/bits/functexcept.h (__throw_out_of_range_fmt): New.
* src/c++11/functexcept.cc (__throw_out_of_range_fmt): New.
* src/c++11/snprintf_lite.cc: New.
* src/c++11/Makefile.am: Add snprintf_lite.cc.
* src/c++11/Makefile.in: Regenerate.
* config/abi/pre/gnu.ver: Add _ZSt24__throw_out_of_range_fmtPKcz.
* include/std/array (at): Use __throw_out_of_range_fmt.
* include/debug/array (at): Likewise.
* include/profile/array (at): Likewise.
* include/std/bitset (_M_check_initial_position, _M_check): New.
(bitset::bitset): Use _M_check_initial_position.
(set, reset, flip, test): Use _M_check.
* include/ext/vstring.h (_M_check, at): Use __throw_out_of_range_fmt.
* include/bits/stl_vector.h (_M_range_check): Likewise.
* include/bits/stl_bvector.h (_M_range_check): Likewise.
* include/bits/stl_deque.h (_M_range_check): Likewise.
* include/bits/basic_string.h (_M_check, at): Likewise.
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust.
* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc:
Likewise.
* testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc:
Likewise.
* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc:
Likewise.
* testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc:
Likewise.
* testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: Likewise.
* testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc:
Likewise.
* testsuite/23_containers/array/tuple_interface/get_neg.cc: Likewise.
* testsuite/23_containers/array/tuple_interface/get_debug_neg.cc: Likewise.
* testsuite/util/exception/safety.h (generate): Use __throw_out_of_range_fmt.

From-SVN: r202818

29 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/functexcept.h
libstdc++-v3/include/bits/stl_bvector.h
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/debug/array
libstdc++-v3/include/ext/vstring.h
libstdc++-v3/include/profile/array
libstdc++-v3/include/std/array
libstdc++-v3/include/std/bitset
libstdc++-v3/src/c++11/Makefile.am
libstdc++-v3/src/c++11/Makefile.in
libstdc++-v3/src/c++11/functexcept.cc
libstdc++-v3/src/c++11/snprintf_lite.cc [new file with mode: 0644]
libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_debug_neg.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc
libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/util/exception/safety.h

index 7f8cae5fb99279f8b2e8a90fe2cd2d658417c6e7..069bd405123e50b02db41cabd23a075af9df3fec 100644 (file)
@@ -1,3 +1,41 @@
+2013-09-21  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+       * include/bits/functexcept.h (__throw_out_of_range_fmt): New.
+       * src/c++11/functexcept.cc (__throw_out_of_range_fmt): New.
+       * src/c++11/snprintf_lite.cc: New.
+       * src/c++11/Makefile.am: Add snprintf_lite.cc.
+       * src/c++11/Makefile.in: Regenerate.
+       * config/abi/pre/gnu.ver: Add _ZSt24__throw_out_of_range_fmtPKcz.
+       * include/std/array (at): Use __throw_out_of_range_fmt.
+       * include/debug/array (at): Likewise.
+       * include/profile/array (at): Likewise.
+       * include/std/bitset (_M_check_initial_position, _M_check): New.
+       (bitset::bitset): Use _M_check_initial_position.
+       (set, reset, flip, test): Use _M_check.
+       * include/ext/vstring.h (_M_check, at): Use __throw_out_of_range_fmt.
+       * include/bits/stl_vector.h (_M_range_check): Likewise.
+       * include/bits/stl_bvector.h (_M_range_check): Likewise.
+       * include/bits/stl_deque.h (_M_range_check): Likewise.
+       * include/bits/basic_string.h (_M_check, at): Likewise.
+       * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust.
+       * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise.
+       * testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc:
+       Likewise.
+       * testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc:
+       Likewise.
+       * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Likewise.
+       * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc: Likewise.
+       * testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc:
+       Likewise.
+       * testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc:
+       Likewise.
+       * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: Likewise.
+       * testsuite/23_containers/array/tuple_interface/tuple_element_debug_neg.cc:
+       Likewise.
+       * testsuite/23_containers/array/tuple_interface/get_neg.cc: Likewise.
+       * testsuite/23_containers/array/tuple_interface/get_debug_neg.cc: Likewise.
+       * testsuite/util/exception/safety.h (generate): Use __throw_out_of_range_fmt.
+
 2013-09-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR testsuite/57605
index 8972fcfca880d920d23213e328a3c424ad883f09..d3c399f6bf2e9465e52cfa15ac0c9dcdd7e20e85 100644 (file)
@@ -1365,6 +1365,9 @@ GLIBCXX_3.4.20 {
     # std::get_unexpected()
     _ZSt14get_unexpectedv;
 
+    # std::__throw_out_of_range_fmt(char const*, ...)
+    _ZSt24__throw_out_of_range_fmtPKcz;
+
 } GLIBCXX_3.4.19;
 
 # Symbols in the support library (libsupc++) have their own tag.
index 4890428886771f042218ec8a219c28622eea6de3..566186f4d172c5671f3e9b9e2968939aa9a1328c 100644 (file)
@@ -321,7 +321,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_check(size_type __pos, const char* __s) const
       {
        if (__pos > this->size())
-         __throw_out_of_range(__N(__s));
+         __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
+                                      "this->size() (which is %zu)"),
+                                  __s, __pos, this->size());
        return __pos;
       }
 
@@ -869,7 +871,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       at(size_type __n) const
       {
        if (__n >= this->size())
-         __throw_out_of_range(__N("basic_string::at"));
+         __throw_out_of_range_fmt(__N("basic_string::at: __n "
+                                      "(which is %zu) >= this->size() "
+                                      "(which is %zu)"),
+                                  __n, this->size());
        return _M_data()[__n];
       }
 
@@ -888,7 +893,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       at(size_type __n)
       {
        if (__n >= size())
-         __throw_out_of_range(__N("basic_string::at"));
+         __throw_out_of_range_fmt(__N("basic_string::at: __n "
+                                      "(which is %zu) >= this->size() "
+                                      "(which is %zu)"),
+                                  __n, this->size());
        _M_leak();
        return _M_data()[__n];
       }
index 161405830770961ceef65b56fa5ef5665ecc6cce..03e2040d96a054ebb328003dea90582cfca361db 100644 (file)
@@ -74,6 +74,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   void
   __throw_out_of_range(const char*) __attribute__((__noreturn__));
 
+  void
+  __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__))
+    __attribute__((__format__(__printf__, 1, 2)));
+
   void
   __throw_runtime_error(const char*) __attribute__((__noreturn__));
 
index 468fad0dbd07c4ce782f57c1f0e4c028f815b0b2..8e4b023061490602edf18ce54119931f86420de8 100644 (file)
@@ -785,7 +785,10 @@ template<typename _Alloc>
     _M_range_check(size_type __n) const
     {
       if (__n >= this->size())
-        __throw_out_of_range(__N("vector<bool>::_M_range_check"));
+       __throw_out_of_range_fmt(__N("vector<bool>::_M_range_check: __n "
+                                    "(which is %zu) >= this->size() "
+                                    "(which is %zu)"),
+                                __n, this->size());
     }
 
   public:
index 98556f59848fa58b36984e1363a9ae5b6609319c..ca9e4179b06f73b83ddce7f71dbfb98df46105b9 100644 (file)
@@ -1264,7 +1264,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_range_check(size_type __n) const
       {
        if (__n >= this->size())
-         __throw_out_of_range(__N("deque::_M_range_check"));
+         __throw_out_of_range_fmt(__N("deque::_M_range_check: __n "
+                                      "(which is %zu)>= this->size() "
+                                      "(which is %zu)"),
+                                  __n, this->size());
       }
 
     public:
index 03850b5e28f9f7920148c8206d2bc4229854c48e..376f39af2169842d5fe0d23841f041169f556a4a 100644 (file)
@@ -785,7 +785,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       _M_range_check(size_type __n) const
       {
        if (__n >= this->size())
-         __throw_out_of_range(__N("vector::_M_range_check"));
+         __throw_out_of_range_fmt(__N("vector::_M_range_check: __n "
+                                      "(which is %zu) >= this->size() "
+                                      "(which is %zu)"),
+                                  __n, this->size());
       }
 
     public:
index d3eea85385677c328d6860604665d7179da802dc..6ee23846518a6e28a79a4328c575414ed7e0dbe0 100644 (file)
@@ -165,7 +165,10 @@ namespace __debug
       at(size_type __n)
       {
        if (__n >= _Nm)
-         std::__throw_out_of_range(__N("array::at"));
+         std::__throw_out_of_range_fmt(__N("array::at: __n "
+                                           "(which is %zu) >= _Nm "
+                                           "(which is %zu)"),
+                                       __n, _Nm);
        return _AT_Type::_S_ref(_M_elems, __n);
       }
 
@@ -175,7 +178,9 @@ namespace __debug
        // Result of conditional expression must be an lvalue so use
        // boolean ? lvalue : (throw-expr, lvalue)
        return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
-         : (std::__throw_out_of_range(__N("array::at")),
+         : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
+                                              ">= _Nm (which is %zu)"),
+                                          __n, _Nm),
             _AT_Type::_S_ref(_M_elems, 0));
       }
 
index bd93c803c236ccfc148d5ccae8a847d38f31e86b..8eb8597c804ea1e6704bfce0f1517c293f71bfc4 100644 (file)
@@ -85,7 +85,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_check(size_type __pos, const char* __s) const
       {
        if (__pos > this->size())
-         std::__throw_out_of_range(__N(__s));
+         std::__throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
+                                           "this->size() (which is %zu)"),
+                                       __s, __pos, this->size());
        return __pos;
       }
 
@@ -575,7 +577,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       at(size_type __n) const
       {
        if (__n >= this->size())
-         std::__throw_out_of_range(__N("__versa_string::at"));
+         std::__throw_out_of_range_fmt(__N("__versa_string::at: __n "
+                                           "(which is %zu) >= this->size() "
+                                           "(which is %zu)"),
+                                       __n, this->size());
        return this->_M_data()[__n];
       }
 
@@ -594,7 +599,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       at(size_type __n)
       {
        if (__n >= this->size())
-         std::__throw_out_of_range(__N("__versa_string::at"));
+         std::__throw_out_of_range_fmt(__N("__versa_string::at: __n "
+                                           "(which is %zu) >= this->size() "
+                                           "(which is %zu)"),
+                                       __n, this->size());
        this->_M_leak();
        return this->_M_data()[__n];
       }
index 33bdc9520968a2440e4e09d43826329edc722227..138ad311ed7c67a7f102d4a0d32ef0306ffcdafb 100644 (file)
@@ -138,7 +138,10 @@ namespace __profile
       at(size_type __n)
       {
        if (__n >= _Nm)
-         std::__throw_out_of_range(__N("array::at"));
+         std::__throw_out_of_range_fmt(__N("array::at: __n "
+                                           "(which is %zu) >= _Nm "
+                                           "(which is %zu)"),
+                                       __n, _Nm);
        return _AT_Type::_S_ref(_M_elems, __n);
       }
 
@@ -148,7 +151,9 @@ namespace __profile
        // Result of conditional expression must be an lvalue so use
        // boolean ? lvalue : (throw-expr, lvalue)
        return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
-         : (std::__throw_out_of_range(__N("array::at")),
+         : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
+                                              ">= _Nm (which is %zu)"),
+                                          __n, _Nm),
             _AT_Type::_S_ref(_M_elems, 0));
       }
 
index 86e8aee14baf21cd2463a04832f3fb9c0791ed2b..673d0e4b18d78c2447e0099b00bb1308cec98dd9 100644 (file)
@@ -180,7 +180,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       at(size_type __n)
       {
        if (__n >= _Nm)
-         std::__throw_out_of_range(__N("array::at"));
+         std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
+                                           ">= _Nm (which is %zu)"),
+                                       __n, _Nm);
        return _AT_Type::_S_ref(_M_elems, __n);
       }
 
@@ -190,7 +192,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        // Result of conditional expression must be an lvalue so use
        // boolean ? lvalue : (throw-expr, lvalue)
        return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
-         : (std::__throw_out_of_range(__N("array::at")),
+         : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
+                                              ">= _Nm (which is %zu)"),
+                                          __n, _Nm),
             _AT_Type::_S_ref(_M_elems, 0));
       }
 
index 1da6baf332f9f503836dc919fdd4f0296a9e36c3..708a434af9e178afda26e2136abcfce5a443b214 100644 (file)
@@ -752,6 +752,26 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       typedef _Base_bitset<_GLIBCXX_BITSET_WORDS(_Nb)> _Base;
       typedef unsigned long _WordT;
 
+      template<class _CharT, class _Traits, class _Alloc>
+      void
+      _M_check_initial_position(const std::basic_string<_CharT, _Traits, _Alloc>& __s,
+                               size_t __position) const
+      {
+       if (__position > __s.size())
+         __throw_out_of_range_fmt(__N("bitset::bitset: __position "
+                                      "(which is %zu) > __s.size() "
+                                      "(which is %zu)"),
+                                  __position, __s.size());
+      }
+
+      void _M_check(size_t __position, const char *__s) const
+      {
+       if (__position >= _Nb)
+         __throw_out_of_range_fmt(__N("%s: __position (which is %zu) "
+                                      ">= _Nb (which is %zu)"),
+                                  __s, __position, _Nb);
+      }
+
       void
       _M_do_sanitize() _GLIBCXX_NOEXCEPT
       { 
@@ -867,9 +887,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
               size_t __position = 0)
        : _Base()
        {
-         if (__position > __s.size())
-           __throw_out_of_range(__N("bitset::bitset initial position "
-                                    "not valid"));
+         _M_check_initial_position(__s, __position);
          _M_copy_from_string(__s, __position,
                              std::basic_string<_CharT, _Traits, _Alloc>::npos,
                              _CharT('0'), _CharT('1'));
@@ -890,9 +908,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
               size_t __position, size_t __n)
        : _Base()
        {
-         if (__position > __s.size())
-           __throw_out_of_range(__N("bitset::bitset initial position "
-                                    "not valid"));
+         _M_check_initial_position(__s, __position);
          _M_copy_from_string(__s, __position, __n, _CharT('0'), _CharT('1'));
        }
 
@@ -904,9 +920,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
               _CharT __zero, _CharT __one = _CharT('1'))
        : _Base()
        {
-         if (__position > __s.size())
-           __throw_out_of_range(__N("bitset::bitset initial position "
-                                    "not valid"));
+         _M_check_initial_position(__s, __position);
          _M_copy_from_string(__s, __position, __n, __zero, __one);
        }
 
@@ -1067,8 +1081,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       bitset<_Nb>&
       set(size_t __position, bool __val = true)
       {
-       if (__position >= _Nb)
-         __throw_out_of_range(__N("bitset::set"));
+       this->_M_check(__position, __N("bitset::set"));
        return _Unchecked_set(__position, __val);
       }
 
@@ -1092,8 +1105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       bitset<_Nb>&
       reset(size_t __position)
       {
-       if (__position >= _Nb)
-         __throw_out_of_range(__N("bitset::reset"));
+       this->_M_check(__position, __N("bitset::reset"));
        return _Unchecked_reset(__position);
       }
       
@@ -1116,8 +1128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       bitset<_Nb>&
       flip(size_t __position)
       {
-       if (__position >= _Nb)
-         __throw_out_of_range(__N("bitset::flip"));
+       this->_M_check(__position, __N("bitset::flip"));
        return _Unchecked_flip(__position);
       }
       
@@ -1302,8 +1313,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       bool
       test(size_t __position) const
       {
-       if (__position >= _Nb)
-         __throw_out_of_range(__N("bitset::test"));
+       this->_M_check(__position, __N("bitset::test"));
        return _Unchecked_test(__position);
       }
 
index 58d3025f0e733be3c84b34b1e133cfc8504d4e24..7dda9483b7bdeaac8beba95b3a9373fa86a890c9 100644 (file)
@@ -42,6 +42,7 @@ sources = \
        random.cc \
        regex.cc  \
        shared_ptr.cc \
+       snprintf_lite.cc \
        system_error.cc \
        thread.cc
 
index 5daae3edf69aba6abc8d9969589a2d34905188af..83b7bd155b9263d072c085e949a50c23effb9320 100644 (file)
@@ -70,7 +70,8 @@ libc__11convenience_la_LIBADD =
 am__objects_1 = chrono.lo condition_variable.lo debug.lo \
        functexcept.lo functional.lo future.lo hash_c++0x.lo \
        hashtable_c++0x.lo limits.lo mutex.lo placeholders.lo \
-       random.lo regex.lo shared_ptr.lo system_error.lo thread.lo
+       random.lo regex.lo shared_ptr.lo snprintf_lite.lo \
+       system_error.lo thread.lo
 @ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = fstream-inst.lo \
 @ENABLE_EXTERN_TEMPLATE_TRUE@  string-inst.lo wstring-inst.lo
 am_libc__11convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
@@ -324,6 +325,7 @@ sources = \
        random.cc \
        regex.cc  \
        shared_ptr.cc \
+       snprintf_lite.cc \
        system_error.cc \
        thread.cc
 
index b0c1804ae04fc972a46b1153f2143442dc10132f..b18f8ad5706840b7db64b29bbdce03c6565c414b 100644 (file)
@@ -31,6 +31,7 @@
 #include <future>
 #include <functional>
 #include <bits/regex_error.h>
+#include <stdarg.h>
 
 #ifdef _GLIBCXX_USE_NLS
 # include <libintl.h>
 # define _(msgid)   (msgid)
 #endif
 
+namespace __gnu_cxx
+{
+  int __snprintf_lite(char *__buf, size_t __bufsize, const char *__fmt,
+                     va_list __ap);
+}
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -79,6 +86,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __throw_out_of_range(const char* __s __attribute__((unused)))
   { _GLIBCXX_THROW_OR_ABORT(out_of_range(_(__s))); }
 
+  void
+  __throw_out_of_range_fmt(const char* __fmt, ...)
+  {
+    const size_t __len = __builtin_strlen(__fmt);
+    // We expect at most 2 numbers, and 1 short string. The additional
+    // 512 bytes should provide more than enough space for expansion.
+    const size_t __alloca_size = __len + 512;
+    char *const __s = static_cast<char*>(__builtin_alloca(__alloca_size));
+    va_list __ap;
+
+    va_start(__ap, __fmt);
+    __gnu_cxx::__snprintf_lite(__s, __alloca_size, __fmt, __ap);
+    _GLIBCXX_THROW_OR_ABORT(out_of_range(_(__s)));
+    va_end(__ap);  // Not reached.
+  }
+
   void
   __throw_runtime_error(const char* __s __attribute__((unused)))
   { _GLIBCXX_THROW_OR_ABORT(runtime_error(_(__s))); }
diff --git a/libstdc++-v3/src/c++11/snprintf_lite.cc b/libstdc++-v3/src/c++11/snprintf_lite.cc
new file mode 100644 (file)
index 0000000..9509c42
--- /dev/null
@@ -0,0 +1,152 @@
+// Debugging support -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of GCC.
+//
+// GCC is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// GCC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <stdarg.h>
+#include <bits/functexcept.h>
+#include <bits/locale_facets.h>
+
+namespace std {
+  template<typename _CharT, typename _ValueT>
+  int
+  __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
+                ios_base::fmtflags __flags, bool __dec);
+}
+
+namespace __gnu_cxx {
+
+  // Private helper to throw logic error if snprintf_lite runs out
+  // of space (which is not expected to ever happen).
+  // NUL-terminates __buf.
+  void
+  __throw_insufficient_space(const char *__buf, const char *__bufend)
+    __attribute__((__noreturn__));
+
+  void
+  __throw_insufficient_space(const char *__buf, const char *__bufend)
+  {
+    // Include space for trailing NUL.
+    const size_t __len = __bufend - __buf + 1;
+
+    const char __err[] = "not enough space for format expansion "
+      "(Please submit full bug report at http://gcc.gnu.org/bugs.html):\n    ";
+    const size_t __errlen = sizeof(__err) - 1;
+
+    char *const __e
+      = static_cast<char*>(__builtin_alloca(__errlen + __len));
+
+    __builtin_memcpy(__e, __err, __errlen);
+    __builtin_memcpy(__e + __errlen, __buf, __len - 1);
+    __e[__errlen + __len - 1] = '\0';
+    std::__throw_logic_error(__e);
+  }
+
+
+  // Private routine to append decimal representation of VAL to the given
+  // BUFFER, but not more than BUFSIZE characters.
+  // Does not NUL-terminate the output buffer.
+  // Returns number of characters appended, or -1 if BUFSIZE is too small.
+  int __concat_size_t(char *__buf, size_t __bufsize, size_t __val)
+  {
+    // Long enough for decimal representation.
+    int __ilen = 3 * sizeof(__val);
+    char *__cs = static_cast<char*>(__builtin_alloca(__ilen));
+    size_t __len = std::__int_to_char(__cs + __ilen, __val,
+                                     std::__num_base::_S_atoms_out,
+                                     std::ios_base::dec, true);
+    if (__bufsize < __len)
+      return -1;
+
+    __builtin_memcpy(__buf, __cs + __ilen - __len, __len);
+    return __len;
+  }
+
+
+  // Private routine to print into __buf arguments according to format,
+  // not to exceed __bufsize.
+  // Only '%%', '%s' and '%zu' format specifiers are understood.
+  // Returns number of characters printed (excluding terminating NUL).
+  // Always NUL-terminates __buf.
+  // Throws logic_error on insufficient space.
+  int __snprintf_lite(char *__buf, size_t __bufsize, const char *__fmt,
+                     va_list __ap)
+  {
+    char *__d = __buf;
+    const char *__s = __fmt;
+    const char *const __limit = __d + __bufsize - 1;  // Leave space for NUL.
+
+    while (__s[0] != '\0' && __d < __limit)
+      {
+       if (__s[0] == '%')
+         switch (__s[1])
+           {
+           default:  // Stray '%'. Just print it.
+             break;
+           case '%':  // '%%'
+             __s += 1;
+             break;
+           case 's':  // '%s'.
+             {
+               const char *__v = va_arg(__ap, const char *);
+
+               while (__v[0] != '\0' && __d < __limit)
+                 *__d++ = *__v++;
+
+               if (__v[0] != '\0')
+                 // Not enough space for __fmt expansion.
+                 __throw_insufficient_space(__buf, __d);
+
+               __s += 2;  // Step over %s.
+               continue;
+             }
+             break;
+           case 'z':
+             if (__s[2] == 'u')  // '%zu' -- expand next size_t arg.
+               {
+                 const int __len = __concat_size_t(__d, __limit - __d,
+                                                   va_arg(__ap, size_t));
+                 if (__len > 0)
+                   __d += __len;
+                 else
+                   // Not enough space for __fmt expansion.
+                   __throw_insufficient_space(__buf, __d);
+
+                 __s += 3;  // Step over %zu
+                 continue;
+               }
+             // Stray '%zX'. Just print it.
+             break;
+           }
+       *__d++ = *__s++;
+      }
+
+    if (__s[0] != '\0')
+      // Not enough space for __fmt expansion.
+      __throw_insufficient_space(__buf, __d);
+
+    *__d = '\0';
+    return __d - __buf;
+  }
+
+}  // __gnu_cxx
index 353577f6bbc1e9a1ad0c6cddf8c5f9a89d306f43..6667629e149db31c463de595dfcb8a225218bcca 100644 (file)
@@ -28,6 +28,6 @@ int n1 = std::get<1>(a);
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 266 }
-// { dg-error "static assertion failed" "" { target *-*-* } 275 }
-// { dg-error "static assertion failed" "" { target *-*-* } 283 }
+// { dg-error "static assertion failed" "" { target *-*-* } 271 }
+// { dg-error "static assertion failed" "" { target *-*-* } 280 }
+// { dg-error "static assertion failed" "" { target *-*-* } 288 }
index d465cd296b9d8b8a416f5f69d28fb4a72d2bf6b8..ca6f9f84e825667db5bb653de120053853be86e7 100644 (file)
@@ -28,6 +28,6 @@ int n1 = std::get<1>(a);
 int n2 = std::get<1>(std::move(a));
 int n3 = std::get<1>(ca);
 
-// { dg-error "static assertion failed" "" { target *-*-* } 270 }
-// { dg-error "static assertion failed" "" { target *-*-* } 279 }
-// { dg-error "static assertion failed" "" { target *-*-* } 287 }
+// { dg-error "static assertion failed" "" { target *-*-* } 274 }
+// { dg-error "static assertion failed" "" { target *-*-* } 283 }
+// { dg-error "static assertion failed" "" { target *-*-* } 291 }
index 76ea230b14e8f91af2f243acbcd81bae5babb7ba..a8e0624ee6e03b5c4015a5d72f678281a6b2f9ae 100644 (file)
@@ -23,4 +23,4 @@
 
 typedef std::tuple_element<1, std::array<int, 1>>::type type;
 
-// { dg-error "static assertion failed" "" { target *-*-* } 300 }
+// { dg-error "static assertion failed" "" { target *-*-* } 305 }
index 3a52607deb690af4cc455ebb0864c36eb101273e..0648bc1176e614344cf204686e544cff87c9fd03 100644 (file)
@@ -23,4 +23,4 @@
 
 typedef std::tuple_element<1, std::array<int, 1>>::type type;
 
-// { dg-error "static assertion failed" "" { target *-*-* } 316 }
+// { dg-error "static assertion failed" "" { target *-*-* } 320 }
index a0bdcdb53f89760bec9c336a48ce2e422d6d7d21..e5917b81f604cc57b659aac524a36de477f507bb 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1755 }
+// { dg-error "no matching" "" { target *-*-* } 1758 }
 
 #include <deque>
 
index 86d7016e616c0f0720836fcdb237e723147941e6..fd83c0e14939d731d05e91ca48e80a657eae60aa 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1688 }
+// { dg-error "no matching" "" { target *-*-* } 1691 }
 
 #include <deque>
 
index 84be8ebda5e8e717ddcb7866f9b3f4104f77ca5d..4dc6e8dec737292b20f3b7ef1a5a44815c899929 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1688 }
+// { dg-error "no matching" "" { target *-*-* } 1691 }
 
 #include <deque>
 #include <utility>
index 26e5c290013ca0e98b639c6bacf3581c5c803395..dbbfbaa5c6dc6e8be7f96a817d7fd1d8cdb3aba0 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1839 }
+// { dg-error "no matching" "" { target *-*-* } 1842 }
 
 #include <deque>
 
@@ -32,4 +32,3 @@ void f()
   std::deque<A> d;
   d.insert(d.begin(), 10, 1);
 }
-
index 388e57182cc46e6ae19d40699370b6fad724a265..b8a6621b33919989b1d0fd27a63f91d79036ecd5 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1302 }
+// { dg-error "no matching" "" { target *-*-* } 1305 }
 
 #include <vector>
 
index 68cfab064f8e9e89d9f21b861ce10273a2cc6a73..ec3aa5a62e896da42a53866689ae7fc562cc02c3 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1228 }
+// { dg-error "no matching" "" { target *-*-* } 1231 }
 
 #include <vector>
 
index 35c03286a26247bf696df24aaece447e91861e5e..5c7d436ad344449a213283c19573d7c7d6bc74ea 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1228 }
+// { dg-error "no matching" "" { target *-*-* } 1231 }
 
 #include <vector>
 #include <utility>
index 6ab70388b83322dfc2d621dec50c66c8bf04503a..2daaf52719738a137f6d36bd0afe812b0e1b4978 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1343 }
+// { dg-error "no matching" "" { target *-*-* } 1346 }
 
 #include <vector>
 
index 5ba9b13ce375069a0406137598d14f39c13a2ef1..ca311797bad2975b0e5cbb8a79d8973c1c0c9aba 100644 (file)
@@ -47,22 +47,12 @@ namespace __gnu_test
       const typename distribution_type::param_type p(0, __max_size);
       size_type random = generator(p);
       if (random < distribution.min() || random > distribution.max())
-       {
-         std::string __s("setup_base::generate");
-         __s += "\n";
-         __s += "random number generated is: ";
-         char buf[40];
-         __builtin_sprintf(buf, "%lu", (unsigned long)random);
-         __s += buf;
-         __s += " on range [";
-         __builtin_sprintf(buf, "%lu", (unsigned long)distribution.min());
-         __s += buf;
-         __s += ", ";
-         __builtin_sprintf(buf, "%lu", (unsigned long)distribution.max());
-         __s += buf;
-         __s += "]\n";
-         std::__throw_out_of_range(__s.c_str());
-       }
+       std::__throw_out_of_range_fmt(__N("setup_base::generate\n"
+                                         "random number generated is: %zu "
+                                         "out of range [%zu, %zu]\n"),
+                                     (size_t)random,
+                                     (size_t)distribution.min(),
+                                     (size_t)distribution.max());
       return random;
     }