re PR libstdc++/26970 (-O3 -Wformat=2 complains about floats written to ostream)
authorPaolo Carlini <pcarlini@suse.de>
Mon, 12 Jun 2006 23:24:22 +0000 (23:24 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 12 Jun 2006 23:24:22 +0000 (23:24 +0000)
2006-06-12  Paolo Carlini  <pcarlini@suse.de>

PR libstdc++/26970
* config/locale/gnu/c_locale.h (__convert_from_v<>): Change to
variadic function, instead of template function.
* config/locale/generic/c_locale.h (__convert_from_v<>): Likewise.
* include/bits/locale_facets.tcc (num_put<>::_M_insert_float):
Adjust.
(money_put<>::do_put(long double)): Likewise.
* src/locale-misc-inst.cc: Remove.
* src/Makefile.am: Adjust.
* src/Makefile.in: Regenerate.

From-SVN: r114591

libstdc++-v3/ChangeLog
libstdc++-v3/config/locale/generic/c_locale.h
libstdc++-v3/config/locale/gnu/c_locale.h
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/src/Makefile.am
libstdc++-v3/src/Makefile.in
libstdc++-v3/src/locale-misc-inst.cc [deleted file]

index 69b390267ac95cdd204f7c617d17bf46a9f7b58c..f1c463207ae51e3bb500328e2a2439396d8117c0 100644 (file)
@@ -1,3 +1,16 @@
+2006-06-12  Paolo Carlini  <pcarlini@suse.de>
+
+       PR libstdc++/26970
+       * config/locale/gnu/c_locale.h (__convert_from_v<>): Change to
+       variadic function, instead of template function.
+       * config/locale/generic/c_locale.h (__convert_from_v<>): Likewise.
+       * include/bits/locale_facets.tcc (num_put<>::_M_insert_float):
+       Adjust.
+       (money_put<>::do_put(long double)): Likewise.
+       * src/locale-misc-inst.cc: Remove.
+       * src/Makefile.am: Adjust.
+       * src/Makefile.in: Regenerate.
+
 2006-06-09  Paolo Carlini  <pcarlini@suse.de>
 
        * include/tr1/random (random_device::random_device(const
index d6e2f65e06ec76d296209f1790208954a931ff4f..d71af1d0a16883909d8860cca391ddf4d8f365bb 100644 (file)
@@ -1,6 +1,7 @@
 // Wrapper for underlying C-language localization -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -40,7 +41,8 @@
 
 #include <clocale>
 #include <cstring>   // get std::strlen
-#include <cstdio>    // get std::snprintf or std::sprintf
+#include <cstdio>    // get std::vsnprintf or std::vsprintf
+#include <cstdarg>
 
 #define _GLIBCXX_NUM_CATEGORIES 0
 
@@ -48,39 +50,42 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   typedef int*                 __c_locale;
 
-  // Convert numeric value of type _Tv to string and return length of
-  // string.  If snprintf is available use it, otherwise fall back to
-  // the unsafe sprintf which, in general, can be dangerous and should
-  // be avoided.
-  template<typename _Tv>
-    int
-    __convert_from_v(char* __out, 
-                    const int __size __attribute__((__unused__)),
-                    const char* __fmt,
-                    _Tv __v, const __c_locale&, int __prec)
-    {
-      char* __old = std::setlocale(LC_NUMERIC, NULL);
-      char* __sav = NULL;
-      if (std::strcmp(__old, "C"))
-       {
-         __sav = new char[std::strlen(__old) + 1];
-         std::strcpy(__sav, __old);
-         std::setlocale(LC_NUMERIC, "C");
-       }
+  // Convert numeric value of type double and long double to string and
+  // return length of string.  If vsnprintf is available use it, otherwise
+  // fall back to the unsafe vsprintf which, in general, can be dangerous
+  // and should be avoided.
+  inline int
+  __convert_from_v(const __c_locale&, char* __out, 
+                  const int __size __attribute__((__unused__)),
+                  const char* __fmt, ...)
+  {
+    char* __old = std::setlocale(LC_NUMERIC, NULL);
+    char* __sav = NULL;
+    if (std::strcmp(__old, "C"))
+      {
+       __sav = new char[std::strlen(__old) + 1];
+       std::strcpy(__sav, __old);
+       std::setlocale(LC_NUMERIC, "C");
+      }
+
+    va_list __args;
+    va_start(__args, __fmt);
 
 #ifdef _GLIBCXX_USE_C99
-      const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
+    const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
 #else
-      const int __ret = std::sprintf(__out, __fmt, __prec, __v);
+    const int __ret = std::vsprintf(__out, __fmt, __args);
 #endif
+
+    va_end(__args);
       
-      if (__sav)
-       {
-         std::setlocale(LC_NUMERIC, __sav);
-         delete [] __sav;
-       }
-      return __ret;
-    }
+    if (__sav)
+      {
+       std::setlocale(LC_NUMERIC, __sav);
+       delete [] __sav;
+      }
+    return __ret;
+  }
 
 _GLIBCXX_END_NAMESPACE
 
index 55e160e1b9beac8b3f3a8c96e417263e3dd682a5..c5a301f9aaa3666560728e093b3120d40124991c 100644 (file)
@@ -1,6 +1,7 @@
 // Wrapper for underlying C-language localization -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 #pragma GCC system_header
 
 #include <cstring>              // get std::strlen
-#include <cstdio>               // get std::snprintf or std::sprintf
+#include <cstdio>               // get std::vsnprintf or std::vsprintf
 #include <clocale>
 #include <langinfo.h>          // For codecvt
 #include <iconv.h>             // For codecvt using iconv, iconv_t
 #include <libintl.h>           // For messages
+#include <cstdarg>
 
 #define _GLIBCXX_C_LOCALE_GNU 1
 
@@ -61,42 +63,44 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   typedef __locale_t           __c_locale;
 
-  // Convert numeric value of type _Tv to string and return length of
-  // string.  If snprintf is available use it, otherwise fall back to
-  // the unsafe sprintf which, in general, can be dangerous and should
-  // be avoided.
-  template<typename _Tv>
-    int
-    __convert_from_v(char* __out, 
-                    const int __size __attribute__ ((__unused__)),
-                    const char* __fmt,
+  // Convert numeric value of type double and long double to string and
+  // return length of string.  If vsnprintf is available use it, otherwise
+  // fall back to the unsafe vsprintf which, in general, can be dangerous
+  // and should be avoided.
+  inline int
+  __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)),
+                  char* __out,
+                  const int __size __attribute__ ((__unused__)),
+                  const char* __fmt, ...)
+  {
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-                    _Tv __v, const __c_locale& __cloc, int __prec)
-    {
-      __c_locale __old = __gnu_cxx::__uselocale(__cloc);
+    __c_locale __old = __gnu_cxx::__uselocale(__cloc);
 #else
-                    _Tv __v, const __c_locale&, int __prec)
-    {
-      char* __old = std::setlocale(LC_ALL, NULL);
-      char* __sav = new char[std::strlen(__old) + 1];
-      std::strcpy(__sav, __old);
-      std::setlocale(LC_ALL, "C");
+    char* __old = std::setlocale(LC_ALL, NULL);
+    char* __sav = new char[std::strlen(__old) + 1];
+    std::strcpy(__sav, __old);
+    std::setlocale(LC_ALL, "C");
 #endif
 
+    va_list __args;
+    va_start(__args, __fmt);
+
 #ifdef _GLIBCXX_USE_C99
-      const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
+    const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
 #else
-      const int __ret = std::sprintf(__out, __fmt, __prec, __v);
+    const int __ret = std::vsprintf(__out, __fmt, __args);
 #endif
 
+    va_end(__args);
+
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-      __gnu_cxx::__uselocale(__old);
+    __gnu_cxx::__uselocale(__old);
 #else
-      std::setlocale(LC_ALL, __sav);
-      delete [] __sav;
+    std::setlocale(LC_ALL, __sav);
+    delete [] __sav;
 #endif
-      return __ret;
-    }
+    return __ret;
+  }
 
 _GLIBCXX_END_NAMESPACE
 
index bfe6fc7f41952a6c154853e084071737a86da79d..485851ecb4da5051c1f0e296d48477f13ca1ca58 100644 (file)
@@ -1135,7 +1135,7 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
       __len = __newlen;
     }
 
-  // The following code uses snprintf (or sprintf(), when
+  // The following code uses vsnprintf (or vsprintf(), when
   // _GLIBCXX_USE_C99 is not defined) to convert floating point values
   // for insertion into a stream.  An optimization would be to replace
   // them with code that works directly on a wide buffer and then use
@@ -1176,16 +1176,16 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
        char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
 
        __num_base::_S_format_float(__io, __fbuf, __mod);
-       __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
-                                     _S_get_c_locale(), __prec);
+       __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                     __fbuf, __prec, __v);
 
        // If the buffer was not large enough, try again with the correct size.
        if (__len >= __cs_size)
          {
            __cs_size = __len + 1;
            __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-           __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v,
-                                         _S_get_c_locale(), __prec);
+           __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                         __fbuf, __prec, __v);
          }
 #else
        // Consider the possibility of long ios_base::fixed outputs
@@ -1203,8 +1203,8 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
        char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
 
        __num_base::_S_format_float(__io, __fbuf, __mod);
-       __len = std::__convert_from_v(__cs, 0, __fbuf, __v,
-                                     _S_get_c_locale(), __prec);
+       __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, 
+                                     __prec, __v);
 #endif
 
        // [22.2.2.2.2] Stage 2, convert to char_type, using correct
@@ -1834,22 +1834,22 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 328. Bad sprintf format modifier in money_put<>::do_put()
-      int __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units,
-                                       _S_get_c_locale(), 0);
+      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                       "%.*Lf", 0, __units);
       // If the buffer was not large enough, try again with the correct size.
       if (__len >= __cs_size)
        {
          __cs_size = __len + 1;
          __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-         __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units,
-                                       _S_get_c_locale(), 0);
+         __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size,
+                                       "%.*Lf", 0, __units);
        }
 #else
       // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'.
       const int __cs_size = numeric_limits<long double>::max_exponent10 + 3;
       char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
-      int __len = std::__convert_from_v(__cs, 0, "%.*Lf", __units,
-                                       _S_get_c_locale(), 0);
+      int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 
+                                       0, __units);
 #endif
       _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
                                                           * __cs_size));
index b3ada6aeddb3eabb96e92df25202caa484660f9a..d54b71ecdac62ae0842e577f43cdd481ba277699 100644 (file)
@@ -162,7 +162,6 @@ sources = \
        istream-inst.cc \
        istream.cc \
        locale-inst.cc \
-       locale-misc-inst.cc \
        misc-inst.cc \
        ostream-inst.cc \
        sstream-inst.cc \
index c6e412e3c5348b8d1d093750f894b259d9689a1a..053ebc602ac398de782ee9d113c26570b07b326f 100644 (file)
@@ -67,9 +67,9 @@ am__libstdc___la_SOURCES_DIST = bitmap_allocator.cc pool_allocator.cc \
        locale_init.cc locale_facets.cc localename.cc stdexcept.cc \
        strstream.cc tree.cc allocator-inst.cc concept-inst.cc \
        fstream-inst.cc ext-inst.cc ios-inst.cc iostream-inst.cc \
-       istream-inst.cc istream.cc locale-inst.cc locale-misc-inst.cc \
-       misc-inst.cc ostream-inst.cc sstream-inst.cc streambuf-inst.cc \
-       streambuf.cc string-inst.cc valarray-inst.cc wlocale-inst.cc \
+       istream-inst.cc istream.cc locale-inst.cc misc-inst.cc \
+       ostream-inst.cc sstream-inst.cc streambuf-inst.cc streambuf.cc \
+       string-inst.cc valarray-inst.cc wlocale-inst.cc \
        wstring-inst.cc atomicity.cc codecvt_members.cc \
        collate_members.cc ctype_members.cc messages_members.cc \
        monetary_members.cc numeric_members.cc time_members.cc \
@@ -87,11 +87,10 @@ am__objects_4 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
        localename.lo stdexcept.lo strstream.lo tree.lo \
        allocator-inst.lo concept-inst.lo fstream-inst.lo ext-inst.lo \
        ios-inst.lo iostream-inst.lo istream-inst.lo istream.lo \
-       locale-inst.lo locale-misc-inst.lo misc-inst.lo \
-       ostream-inst.lo sstream-inst.lo streambuf-inst.lo streambuf.lo \
-       string-inst.lo valarray-inst.lo wlocale-inst.lo \
-       wstring-inst.lo $(am__objects_1) $(am__objects_2) \
-       $(am__objects_3)
+       locale-inst.lo misc-inst.lo ostream-inst.lo sstream-inst.lo \
+       streambuf-inst.lo streambuf.lo string-inst.lo valarray-inst.lo \
+       wlocale-inst.lo wstring-inst.lo $(am__objects_1) \
+       $(am__objects_2) $(am__objects_3)
 am_libstdc___la_OBJECTS = $(am__objects_4)
 libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -366,7 +365,6 @@ sources = \
        istream-inst.cc \
        istream.cc \
        locale-inst.cc \
-       locale-misc-inst.cc \
        misc-inst.cc \
        ostream-inst.cc \
        sstream-inst.cc \
diff --git a/libstdc++-v3/src/locale-misc-inst.cc b/libstdc++-v3/src/locale-misc-inst.cc
deleted file mode 100644 (file)
index 8af7359..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Locale support -*- C++ -*-
-
-// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2006
-// Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library.  This library 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 2, or (at your option)
-// any later version.
-
-// This library 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.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING.  If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction.  Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License.  This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-//
-// ISO C++ 14882: 22.1  Locales
-//
-
-#include <locale>
-
-_GLIBCXX_BEGIN_NAMESPACE(std)
-
-  template
-    int
-    __convert_from_v(char*, const int, const char*, double, 
-                    const __c_locale&, int);
-
-  template
-    int
-    __convert_from_v(char*, const int, const char*, long double, 
-                    const __c_locale&, int);
-
-_GLIBCXX_END_NAMESPACE
-
-// XXX GLIBCXX_ABI Deprecated
-#if defined _GLIBCXX_LONG_DOUBLE_COMPAT
-
-#define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \
-  extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak))
-
-# if _GLIBCXX_C_LOCALE_GNU
-_GLIBCXX_LDBL_COMPAT(_ZSt16__convert_from_vIdEiPciPKcT_RKP15__locale_structi,
-                    _ZSt16__convert_from_vIeEiPciPKcT_RKP15__locale_structi);
-# else
-_GLIBCXX_LDBL_COMPAT(_ZSt16__convert_from_vIdEiPciPKcT_RKPii,
-                    _ZSt16__convert_from_vIeEiPciPKcT_RKPii);
-# endif
-
-#endif // _GLIBCXX_LONG_DOUBLE_COMPAT