re PR libstdc++/26970 (-O3 -Wformat=2 complains about floats written to ostream)
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
This commit is contained in:
parent
4c65a5340d
commit
964c53299c
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
@ -39,11 +40,12 @@
|
||||
#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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 \
|
||||
|
@ -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 \
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user