diff mbox

[google,gcc-4_8] Applied partial backport of r202818, r202832 and r202836.

Message ID ye6qd2nwmtqk.fsf@elbrus2.mtv.corp.google.com
State New
Headers show

Commit Message

Paul Pluzhnikov Sept. 25, 2013, 10:17 p.m. UTC
Greetings,

I committed partial backport of r202818, r202832 and r202836 to
google/gcc-4_8 branch as r202927.


2013-09-25  Paul Pluzhnikov  <ppluzhnikov@google.com>

	* libstdc++-v3/config/abi/pre/gnu.ver: Add _ZSt24__throw_out_of_range_fmtPKcz
	* libstdc++-v3/src/c++11/Makefile.am: Add snprintf_lite.
	* libstdc++-v3/src/c++11/Makefile.in: Regenerate.
	* libstdc++-v3/src/c++11/snprintf_lite.cc: New.
	* libstdc++-v3/src/c++11/functexcept.cc (__throw_out_of_range_fmt): New.
diff mbox

Patch

Index: libstdc++-v3/config/abi/pre/gnu.ver
===================================================================
--- libstdc++-v3/config/abi/pre/gnu.ver	(revision 202926)
+++ libstdc++-v3/config/abi/pre/gnu.ver	(working copy)
@@ -1357,6 +1357,13 @@ 
 
 } GLIBCXX_3.4.18;
 
+GLIBCXX_3.4.20 {
+
+   # 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.
 CXXABI_1.3 {
 
Index: libstdc++-v3/src/c++11/Makefile.am
===================================================================
--- libstdc++-v3/src/c++11/Makefile.am	(revision 202926)
+++ libstdc++-v3/src/c++11/Makefile.am	(working copy)
@@ -42,6 +42,7 @@ 
 	random.cc \
 	regex.cc  \
 	shared_ptr.cc \
+	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc
 
Index: libstdc++-v3/src/c++11/functexcept.cc
===================================================================
--- libstdc++-v3/src/c++11/functexcept.cc	(revision 202926)
+++ libstdc++-v3/src/c++11/functexcept.cc	(working copy)
@@ -31,6 +31,7 @@ 
 #include <future>
 #include <functional>
 #include <regex>
+#include <stdarg.h>
 
 #ifdef _GLIBCXX_USE_NLS
 # include <libintl.h>
@@ -39,6 +40,12 @@ 
 # 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
@@ -80,6 +87,22 @@ 
   { _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))); }
 
Index: libstdc++-v3/src/c++11/Makefile.in
===================================================================
--- libstdc++-v3/src/c++11/Makefile.in	(revision 202926)
+++ libstdc++-v3/src/c++11/Makefile.in	(working copy)
@@ -70,7 +70,8 @@ 
 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)
@@ -319,6 +320,7 @@ 
 	random.cc \
 	regex.cc  \
 	shared_ptr.cc \
+	snprintf_lite.cc \
 	system_error.cc \
 	thread.cc
 
Index: libstdc++-v3/src/c++11/snprintf_lite.cc
===================================================================
--- libstdc++-v3/src/c++11/snprintf_lite.cc	(revision 0)
+++ libstdc++-v3/src/c++11/snprintf_lite.cc	(revision 0)
@@ -0,0 +1,159 @@ 
+// 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)
+  {
+    // __int_to_char is explicitly instantiated and available only for
+    // some, but not all, types. See locale-inst.cc.
+#ifdef _GLIBCXX_USE_LONG_LONG
+    unsigned long long __val2 = __val;
+#else
+    unsigned long __val2 = __val;
+#endif
+    // Long enough for decimal representation.
+    int __ilen = 3 * sizeof(__val2);
+    char *__cs = static_cast<char*>(__builtin_alloca(__ilen));
+    size_t __len = std::__int_to_char(__cs + __ilen, __val2,
+				      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