aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2009-07-18 22:58:10 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2009-07-18 22:58:10 +0000
commitaf90c8c9ae3b795f28cabd9f11e9f7c9a1ccccb4 (patch)
tree7563faaf990f548d8b0ebbb3e082086e798b7386 /libstdc++-v3/include
parent827f4079406b72fce7b49a29abe60ecb801462d5 (diff)
downloadgcc-af90c8c9ae3b795f28cabd9f11e9f7c9a1ccccb4.zip
gcc-af90c8c9ae3b795f28cabd9f11e9f7c9a1ccccb4.tar.gz
gcc-af90c8c9ae3b795f28cabd9f11e9f7c9a1ccccb4.tar.bz2
re PR libstdc++/40712 (locale(const locale&, const char*, locale::category) can create broken locale)
2009-07-18 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/40712 * config/locale/gnu/numeric_members.cc (numpunct<>:: _M_initialize_numpunct): Dynamically allocate _M_data->_M_grouping and copy the langinfo data into it. (numpunct<>::~numpunct): Free the allocated memory. * config/locale/gnu/monetary_members.cc (moneypunct<>:: _M_initialize_moneypunct): Dynamically allocate _M_data->_M_grouping, _M_data->_M_positive_sign, _M_data->_M_negative_sign, _M_data->_M_curr_symbol. (moneypunct<>::~moneypunct): Free the allocated memory. * testsuite/22_locale/moneypunct/40712.cc: New. * include/bits/locale_facets.tcc (__numpunct_cache<>::_M_cache): Do not leak memory if new throws. * include/bits/locale_facets_nonio.tcc (__moneypunct_cache<>::_M_cache): Likewise. From-SVN: r149782
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc69
-rw-r--r--libstdc++-v3/include/bits/locale_facets_nonio.tcc75
2 files changed, 87 insertions, 57 deletions
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 85b4ec6..1608e2c 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -81,33 +81,48 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
- _M_grouping_size = __np.grouping().size();
- char* __grouping = new char[_M_grouping_size];
- __np.grouping().copy(__grouping, _M_grouping_size);
- _M_grouping = __grouping;
- _M_use_grouping = (_M_grouping_size
- && static_cast<signed char>(_M_grouping[0]) > 0
- && (_M_grouping[0]
- != __gnu_cxx::__numeric_traits<char>::__max));
-
- _M_truename_size = __np.truename().size();
- _CharT* __truename = new _CharT[_M_truename_size];
- __np.truename().copy(__truename, _M_truename_size);
- _M_truename = __truename;
-
- _M_falsename_size = __np.falsename().size();
- _CharT* __falsename = new _CharT[_M_falsename_size];
- __np.falsename().copy(__falsename, _M_falsename_size);
- _M_falsename = __falsename;
-
- _M_decimal_point = __np.decimal_point();
- _M_thousands_sep = __np.thousands_sep();
-
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
- __ct.widen(__num_base::_S_atoms_out,
- __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out);
- __ct.widen(__num_base::_S_atoms_in,
- __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in);
+ char* __grouping = 0;
+ _CharT* __truename = 0;
+ _CharT* __falsename = 0;
+ __try
+ {
+ _M_grouping_size = __np.grouping().size();
+ __grouping = new char[_M_grouping_size];
+ __np.grouping().copy(__grouping, _M_grouping_size);
+ _M_grouping = __grouping;
+ _M_use_grouping = (_M_grouping_size
+ && static_cast<signed char>(_M_grouping[0]) > 0
+ && (_M_grouping[0]
+ != __gnu_cxx::__numeric_traits<char>::__max));
+
+ _M_truename_size = __np.truename().size();
+ __truename = new _CharT[_M_truename_size];
+ __np.truename().copy(__truename, _M_truename_size);
+ _M_truename = __truename;
+
+ _M_falsename_size = __np.falsename().size();
+ __falsename = new _CharT[_M_falsename_size];
+ __np.falsename().copy(__falsename, _M_falsename_size);
+ _M_falsename = __falsename;
+
+ _M_decimal_point = __np.decimal_point();
+ _M_thousands_sep = __np.thousands_sep();
+
+ const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
+ __ct.widen(__num_base::_S_atoms_out,
+ __num_base::_S_atoms_out
+ + __num_base::_S_oend, _M_atoms_out);
+ __ct.widen(__num_base::_S_atoms_in,
+ __num_base::_S_atoms_in
+ + __num_base::_S_iend, _M_atoms_in);
+ }
+ __catch(...)
+ {
+ delete [] __grouping;
+ delete [] __truename;
+ delete [] __falsename;
+ __throw_exception_again;
+ }
}
// Used by both numeric and monetary facets.
diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index 06bbfcf4..96feeaf 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -71,40 +71,55 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
const moneypunct<_CharT, _Intl>& __mp =
use_facet<moneypunct<_CharT, _Intl> >(__loc);
- _M_grouping_size = __mp.grouping().size();
- char* __grouping = new char[_M_grouping_size];
- __mp.grouping().copy(__grouping, _M_grouping_size);
- _M_grouping = __grouping;
- _M_use_grouping = (_M_grouping_size
- && static_cast<signed char>(_M_grouping[0]) > 0
- && (_M_grouping[0]
- != __gnu_cxx::__numeric_traits<char>::__max));
-
_M_decimal_point = __mp.decimal_point();
_M_thousands_sep = __mp.thousands_sep();
_M_frac_digits = __mp.frac_digits();
-
- _M_curr_symbol_size = __mp.curr_symbol().size();
- _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size];
- __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
- _M_curr_symbol = __curr_symbol;
-
- _M_positive_sign_size = __mp.positive_sign().size();
- _CharT* __positive_sign = new _CharT[_M_positive_sign_size];
- __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
- _M_positive_sign = __positive_sign;
-
- _M_negative_sign_size = __mp.negative_sign().size();
- _CharT* __negative_sign = new _CharT[_M_negative_sign_size];
- __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
- _M_negative_sign = __negative_sign;
-
- _M_pos_format = __mp.pos_format();
- _M_neg_format = __mp.neg_format();
- const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
- __ct.widen(money_base::_S_atoms,
- money_base::_S_atoms + money_base::_S_end, _M_atoms);
+ char* __grouping = 0;
+ _CharT* __curr_symbol = 0;
+ _CharT* __positive_sign = 0;
+ _CharT* __negative_sign = 0;
+ __try
+ {
+ _M_grouping_size = __mp.grouping().size();
+ __grouping = new char[_M_grouping_size];
+ __mp.grouping().copy(__grouping, _M_grouping_size);
+ _M_grouping = __grouping;
+ _M_use_grouping = (_M_grouping_size
+ && static_cast<signed char>(_M_grouping[0]) > 0
+ && (_M_grouping[0]
+ != __gnu_cxx::__numeric_traits<char>::__max));
+
+ _M_curr_symbol_size = __mp.curr_symbol().size();
+ __curr_symbol = new _CharT[_M_curr_symbol_size];
+ __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size);
+ _M_curr_symbol = __curr_symbol;
+
+ _M_positive_sign_size = __mp.positive_sign().size();
+ __positive_sign = new _CharT[_M_positive_sign_size];
+ __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size);
+ _M_positive_sign = __positive_sign;
+
+ _M_negative_sign_size = __mp.negative_sign().size();
+ __negative_sign = new _CharT[_M_negative_sign_size];
+ __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size);
+ _M_negative_sign = __negative_sign;
+
+ _M_pos_format = __mp.pos_format();
+ _M_neg_format = __mp.neg_format();
+
+ const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc);
+ __ct.widen(money_base::_S_atoms,
+ money_base::_S_atoms + money_base::_S_end, _M_atoms);
+ }
+ __catch(...)
+ {
+ delete [] __grouping;
+ delete [] __curr_symbol;
+ delete [] __positive_sign;
+ delete [] __negative_sign;
+ __throw_exception_again;
+ }
}
_GLIBCXX_BEGIN_LDBL_NAMESPACE