extern numpunct<char> numpunct_c;
extern num_get<char> num_get_c;
extern num_put<char> num_put_c;
-extern codecvt<char, char, mbstate_t> codecvt_c;
+ extern codecvt<char, char, mbstate_t> codecvt_c;
extern moneypunct<char, false> moneypunct_cf;
extern moneypunct<char, true> moneypunct_ct;
extern money_get<char> money_get_c;
_Impl(const _Impl& __imp, size_t __refs)
: _M_references(__refs), _M_facets_size(__imp._M_facets_size)
{
+ _M_facets = _M_caches = 0;
+ _M_names = 0;
try
- {
+ {
_M_facets = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_facets[__i] = 0;
+ _M_caches = new const facet*[_M_facets_size];
+ _M_names = new char*[_S_categories_size];
}
- catch(...)
+ catch(...)
{
delete [] _M_facets;
+ delete [] _M_caches;
__throw_exception_again;
}
+
for (size_t __i = 0; __i < _M_facets_size; ++__i)
{
_M_facets[__i] = __imp._M_facets[__i];
+ _M_caches[__i] = __imp._M_caches[__i];
if (_M_facets[__i])
_M_facets[__i]->_M_add_reference();
- }
-
- try
- {
- _M_caches = new const facet*[_M_facets_size];
- }
- catch(...)
- {
- delete [] _M_caches;
- __throw_exception_again;
- }
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- {
- _M_caches[__i] = __imp._M_caches[__i];
if (_M_caches[__i])
- _M_caches[__i]->_M_add_reference();
+ _M_caches[__i]->_M_add_reference();
}
- try
+ // Name all the categories.
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ _M_names[__i] = 0;
+ try
{
- _M_names = new char*[_S_categories_size];
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ {
+ char* __new = new char[std::strlen(__imp._M_names[__i]) + 1];
+ std::strcpy(__new, __imp._M_names[__i]);
+ _M_names[__i] = __new;
+ }
}
catch(...)
{
- delete [] _M_names;
+ this->~_Impl();
__throw_exception_again;
}
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- {
- char* __new = new char[strlen(__imp._M_names[__i]) + 1];
- std::strcpy(__new, __imp._M_names[__i]);
- _M_names[__i] = __new;
- }
}
// Construct named _Impl.
__c_locale __cloc;
locale::facet::_S_create_c_locale(__cloc, __s);
+ _M_facets = _M_caches = 0;
+ _M_names = 0;
try
- {
- _M_facets = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_facets[__i] = 0;
- }
- catch(...)
{
- delete [] _M_facets;
- __throw_exception_again;
- }
-
- try
- {
- _M_caches = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_caches[__i] = 0;
+ _M_facets = new const facet*[_M_facets_size];
+ _M_caches = new const facet*[_M_facets_size];
+ _M_names = new char*[_S_categories_size];
}
catch(...)
{
+ delete [] _M_facets;
delete [] _M_caches;
__throw_exception_again;
- }
+ }
+
+ for (size_t __i = 0; __i < _M_facets_size; ++__i)
+ _M_facets[__i] = _M_caches[__i] = 0;
// Name all the categories.
- try
- {
- _M_names = new char*[_S_categories_size];
- }
- catch(...)
- {
- delete [] _M_names;
- __throw_exception_again;
- }
- size_t __len = std::strlen(__s);
- if (!std::strchr(__s, ';'))
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ _M_names[__i] = 0;
+ try
{
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ const size_t __len = std::strlen(__s);
+ if (!std::strchr(__s, ';'))
{
- _M_names[__i] = new char[__len + 1];
- std::strcpy(_M_names[__i], __s);
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ {
+ _M_names[__i] = new char[__len + 1];
+ std::strcpy(_M_names[__i], __s);
+ }
}
- }
- else
- {
- const char* __beg = __s;
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ else
{
- __beg = std::strchr(__beg, '=') + 1;
- const char* __end = std::strchr(__beg, ';');
- if (!__end)
- __end = __s + __len;
- char* __new = new char[__end - __beg + 1];
- std::memcpy(__new, __beg, __end - __beg);
- __new[__end - __beg] = '\0';
- _M_names[__i] = __new;
+ const char* __beg = __s;
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ {
+ __beg = std::strchr(__beg, '=') + 1;
+ const char* __end = std::strchr(__beg, ';');
+ if (!__end)
+ __end = __s + __len;
+ char* __new = new char[__end - __beg + 1];
+ std::memcpy(__new, __beg, __end - __beg);
+ __new[__end - __beg] = '\0';
+ _M_names[__i] = __new;
+ }
}
}
+ catch(...)
+ {
+ this->~_Impl();
+ __throw_exception_again;
+ }
- // Construct all standard facets and add them to _M_facets.
+ // Construct all standard facets and add them to _M_facets.
_M_init_facet(new std::ctype<char>(__cloc, 0, false));
_M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
_M_init_facet(new numpunct<char>(__cloc));
_M_init_facet(new time_put<wchar_t>);
_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
#endif
+
locale::facet::_S_destroy_c_locale(__cloc);
}
locale::facet::_S_c_name);
_M_facets = new (&facet_vec) const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_facets[__i] = 0;
-
_M_caches = new (&cache_vec) const facet*[_M_facets_size];
for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_caches[__i] = 0;
+ _M_facets[__i] = _M_caches[__i] = 0;
// Name all the categories.
_M_names = new (&name_vec) char*[_S_categories_size];
for (size_t __i = 0; __i < _S_categories_size; ++__i)
{
_M_names[__i] = new (&name_c[__i]) char[2];
- strcpy(_M_names[__i], locale::facet::_S_c_name);
+ std::strcpy(_M_names[__i], locale::facet::_S_c_name);
}
// This is needed as presently the C++ version of "C" locales
_M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
_M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
#endif
-
+
// This locale is safe to pre-cache, after all the facets have
// been created and installed.
_M_caches[numpunct<char>::id._M_id()] = __npc;
if (std::strcmp(_M_names[__ix], "*") != 0
&& std::strcmp(__imp->_M_names[__ix], "*") != 0)
{
- delete [] _M_names[__ix];
char* __new = new char[std::strlen(__imp->_M_names[__ix]) + 1];
std::strcpy(__new, __imp->_M_names[__ix]);
+ delete [] _M_names[__ix];
_M_names[__ix] = __new;
}
}
// New cache array.
const facet** __oldc = _M_caches;
const facet** __newc;
- __newc = new const facet*[__new_size];
+ try
+ {
+ __newc = new const facet*[__new_size];
+ }
+ catch(...)
+ {
+ delete [] __newf;
+ __throw_exception_again;
+ }
for (size_t __i = 0; __i < _M_facets_size; ++__i)
__newc[__i] = _M_caches[__i];
for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
--- /dev/null
+// Copyright (C) 2003 Free Software Foundation
+//
+// 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 22.1.1.2 locale constructors and destructors [lib.locale.cons]
+
+#include <new>
+#include <locale>
+#include <cstdlib>
+#include <cstring>
+
+int times_to_fail = 0;
+
+void* allocate(std::size_t n)
+{
+ if (!times_to_fail--)
+ return 0;
+
+ void* ret = std::malloc(n ? n : 1);
+ if (ret)
+ std::memset(ret, 0xbc, n);
+ return ret;
+}
+
+void deallocate(void* p)
+{
+ if (p)
+ std::free(p);
+}
+
+void* operator new(std::size_t n) throw (std::bad_alloc)
+{
+ void* ret = allocate(n);
+ if (!ret)
+ throw std::bad_alloc();
+ return ret;
+}
+
+void* operator new[](std::size_t n) throw (std::bad_alloc)
+{
+ void* ret = allocate(n);
+ if (!ret)
+ throw std::bad_alloc();
+ return ret;
+}
+
+void operator delete(void* p) throw()
+{
+ deallocate(p);
+}
+
+void operator delete[](void* p) throw()
+{
+ deallocate(p);
+}
+
+void* operator new(std::size_t n, const std::nothrow_t&) throw()
+{
+ return allocate(n);
+}
+
+void* operator new[](std::size_t n, const std::nothrow_t&) throw()
+{
+ return allocate(n);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+ deallocate(p);
+}
+
+void operator delete[](void* p, const std::nothrow_t&) throw()
+{
+ deallocate(p);
+}
+
+// libstdc++/12352
+void test01(int iters)
+{
+ using namespace std;
+ bool test = true;
+
+ for (int j = 0; j < iters; ++j)
+ {
+ for (int i = 0; i < 100; ++i)
+ {
+ times_to_fail = i;
+ try
+ {
+ locale loc1("");
+ locale loc2(loc1, locale::classic(), locale::numeric);
+ }
+ catch (exception&)
+ {
+ }
+ }
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ int iters = 1;
+ if (argc > 1)
+ iters = std::atoi(argv[1]);
+ if (iters < 1)
+ iters = 1;
+ test01(iters);
+
+ return 0;
+}