diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 79c9b4e09d3..320a7617dea 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2014-12-10 Jonathan Wakely + + * include/bits/locale_facets.tcc (numpunct::_M_cache): Avoid calling + virtual functions twice. Only update _M_allocated after all + allocations have succeeded. + * include/bits/locale_facets_nonio.tcc (moneypunct::_M_cache): + Likewise. + * include/bits/locale_facets_nonio.h (__timepunct::_M_cache): Remove + unused declaration. + 2014-12-09 Jonathan Wakely PR libstdc++/64203 diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 88adc0d9832..200e099b2a5 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -77,8 +77,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void __numpunct_cache<_CharT>::_M_cache(const locale& __loc) { - _M_allocated = true; - const numpunct<_CharT>& __np = use_facet >(__loc); char* __grouping = 0; @@ -86,24 +84,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _CharT* __falsename = 0; __try { - _M_grouping_size = __np.grouping().size(); + const string& __g = __np.grouping(); + _M_grouping_size = __g.size(); __grouping = new char[_M_grouping_size]; - __np.grouping().copy(__grouping, _M_grouping_size); - _M_grouping = __grouping; + __g.copy(__grouping, _M_grouping_size); _M_use_grouping = (_M_grouping_size - && static_cast(_M_grouping[0]) > 0 - && (_M_grouping[0] + && static_cast(__grouping[0]) > 0 + && (__grouping[0] != __gnu_cxx::__numeric_traits::__max)); - _M_truename_size = __np.truename().size(); + const basic_string<_CharT>& __tn = __np.truename(); + _M_truename_size = __tn.size(); __truename = new _CharT[_M_truename_size]; - __np.truename().copy(__truename, _M_truename_size); - _M_truename = __truename; + __tn.copy(__truename, _M_truename_size); - _M_falsename_size = __np.falsename().size(); + const basic_string<_CharT>& __fn = __np.falsename(); + _M_falsename_size = __fn.size(); __falsename = new _CharT[_M_falsename_size]; - __np.falsename().copy(__falsename, _M_falsename_size); - _M_falsename = __falsename; + __fn.copy(__falsename, _M_falsename_size); _M_decimal_point = __np.decimal_point(); _M_thousands_sep = __np.thousands_sep(); @@ -115,6 +113,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __ct.widen(__num_base::_S_atoms_in, __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); + + _M_grouping = __grouping; + _M_truename = __truename; + _M_falsename = __falsename; + _M_allocated = true; } __catch(...) { diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h index 5c1eeb7928b..1b0aff9b5c5 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.h +++ b/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -138,9 +138,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~__timepunct_cache(); - void - _M_cache(const locale& __loc); - private: __timepunct_cache& operator=(const __timepunct_cache&); diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index c9f8dac1d1d..42c3504667e 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -68,8 +68,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) { - _M_allocated = true; - const moneypunct<_CharT, _Intl>& __mp = use_facet >(__loc); @@ -83,29 +81,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _CharT* __negative_sign = 0; __try { - _M_grouping_size = __mp.grouping().size(); + const string& __g = __mp.grouping(); + _M_grouping_size = __g.size(); __grouping = new char[_M_grouping_size]; - __mp.grouping().copy(__grouping, _M_grouping_size); - _M_grouping = __grouping; + __g.copy(__grouping, _M_grouping_size); _M_use_grouping = (_M_grouping_size - && static_cast(_M_grouping[0]) > 0 - && (_M_grouping[0] + && static_cast(__grouping[0]) > 0 + && (__grouping[0] != __gnu_cxx::__numeric_traits::__max)); - _M_curr_symbol_size = __mp.curr_symbol().size(); + const basic_string<_CharT>& __cs = __mp.curr_symbol(); + _M_curr_symbol_size = __cs.size(); __curr_symbol = new _CharT[_M_curr_symbol_size]; - __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); - _M_curr_symbol = __curr_symbol; + __cs.copy(__curr_symbol, _M_curr_symbol_size); - _M_positive_sign_size = __mp.positive_sign().size(); + const basic_string<_CharT>& __ps = __mp.positive_sign(); + _M_positive_sign_size = __ps.size(); __positive_sign = new _CharT[_M_positive_sign_size]; - __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); - _M_positive_sign = __positive_sign; + __ps.copy(__positive_sign, _M_positive_sign_size); - _M_negative_sign_size = __mp.negative_sign().size(); + const basic_string<_CharT>& __ns = __mp.negative_sign(); + _M_negative_sign_size = __ns.size(); __negative_sign = new _CharT[_M_negative_sign_size]; - __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); - _M_negative_sign = __negative_sign; + __ns.copy(__negative_sign, _M_negative_sign_size); _M_pos_format = __mp.pos_format(); _M_neg_format = __mp.neg_format(); @@ -113,6 +111,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const ctype<_CharT>& __ct = use_facet >(__loc); __ct.widen(money_base::_S_atoms, money_base::_S_atoms + money_base::_S_end, _M_atoms); + + _M_grouping = __grouping; + _M_curr_symbol = __curr_symbol; + _M_positive_sign = __positive_sign; + _M_negative_sign = __negative_sign; + _M_allocated = true; } __catch(...) {