]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 5 Dec 2002 23:48:57 +0000 (23:48 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Thu, 5 Dec 2002 23:48:57 +0000 (23:48 +0000)
2002-12-05  Benjamin Kosnik  <bkoz@redhat.com>

* config/linker-map.gnu: Put _S_force_new into GLIBCPP_3.2.2.
* testsuite/abi_check.cc: Add GLIBCPP_3.2.2.

2002-12-05  Benjamin Kosnik  <bkoz@redhat.com>
            Gabriel Dos Reis  <gdr@integrable-solutions.net>

PR libstdc++/8230
* include/bits/stl_alloc.h: Use builtin_expect for the most
obvious limit checks.
(__default_alloc_template::allocate): Check for null, throw
bad_alloc.
* testsuite/20_util/allocator_members.cc (test02): Add.
* testsuite/23_containers/vector_capacity.cc (test03): Add.

2002-12-05  Loren J. Rittle  <ljrittle@acm.org>
    Brad Spencer  <spencer@infointeractive.com>
    (provided alternate patch and improvements)

PR libstdc++/8708
* docs/html/23_containers/howto.html (GLIBCPP_FORCE_NEW): Document
new environment variable which replaces all uses of __USE_MALLOC
macro.
* docs/html/ext/howto.html (GLIBCPP_FORCE_NEW): Likewise.
(__mem_interface): Remove all references to old internal typedef.
* include/backward/alloc.h (__USE_MALLOC): Remove it and all
guarded code.
* include/bits/c++config (__USE_MALLOC): Update related error
message and comment.
* include/bits/stl_alloc.h (__USE_MALLOC): Remove it and all
guarded code.  Update all related comments.
(__mem_interface): Unconditionally replace it with __new_alloc.
However, leave the typedef around in case anyone used it.
(__default_alloc_template<>::_S_force_new): New class static.
(__default_alloc_template<>::allocate, deallocate): Add
run-time controlled feature similar to what __USE_MALLOC code
path had provided.
* src/stl-inst.cc (__USE_MALLOC): Remove it and all
guarded code.
* testsuite/21_strings/capacity.cc: Remove reference to __USE_MALLOC.
Add documentation on GLIBCPP_FORCE_NEW environment variable.
* testsuite/ext/allocators.cc: Likewise.

From-SVN: r59873

13 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/linker-map.gnu
libstdc++-v3/docs/html/23_containers/howto.html
libstdc++-v3/docs/html/ext/howto.html
libstdc++-v3/include/backward/alloc.h
libstdc++-v3/include/bits/c++config
libstdc++-v3/include/bits/stl_alloc.h
libstdc++-v3/src/stl-inst.cc
libstdc++-v3/testsuite/20_util/allocator_members.cc
libstdc++-v3/testsuite/21_strings/capacity.cc
libstdc++-v3/testsuite/23_containers/vector_capacity.cc
libstdc++-v3/testsuite/abi_check.cc
libstdc++-v3/testsuite/ext/allocators.cc

index bac4c721a11b1109ff9d46f4b063f010cea7712b..d3e059243a0ee1ca7698a1383522f53d460c2d1d 100644 (file)
@@ -1,3 +1,47 @@
+2002-12-05  Benjamin Kosnik  <bkoz@redhat.com>
+
+       * config/linker-map.gnu: Put _S_force_new into GLIBCPP_3.2.2.
+       * testsuite/abi_check.cc: Add GLIBCPP_3.2.2.
+
+2002-12-05  Benjamin Kosnik  <bkoz@redhat.com>
+            Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+       PR libstdc++/8230
+       * include/bits/stl_alloc.h: Use builtin_expect for the most
+       obvious limit checks.
+       (__default_alloc_template::allocate): Check for null, throw
+       bad_alloc.
+       * testsuite/20_util/allocator_members.cc (test02): Add.
+       * testsuite/23_containers/vector_capacity.cc (test03): Add.
+
+2002-12-05  Loren J. Rittle  <ljrittle@acm.org>
+           Brad Spencer  <spencer@infointeractive.com> 
+           (provided alternate patch and improvements)
+
+       PR libstdc++/8708
+       * docs/html/23_containers/howto.html (GLIBCPP_FORCE_NEW): Document
+       new environment variable which replaces all uses of __USE_MALLOC
+       macro.
+       * docs/html/ext/howto.html (GLIBCPP_FORCE_NEW): Likewise.
+       (__mem_interface): Remove all references to old internal typedef.
+       * include/backward/alloc.h (__USE_MALLOC): Remove it and all
+       guarded code.
+       * include/bits/c++config (__USE_MALLOC): Update related error
+       message and comment.
+       * include/bits/stl_alloc.h (__USE_MALLOC): Remove it and all
+       guarded code.  Update all related comments.
+       (__mem_interface): Unconditionally replace it with __new_alloc.
+       However, leave the typedef around in case anyone used it.
+       (__default_alloc_template<>::_S_force_new): New class static.
+       (__default_alloc_template<>::allocate, deallocate): Add
+       run-time controlled feature similar to what __USE_MALLOC code
+       path had provided.
+       * src/stl-inst.cc (__USE_MALLOC): Remove it and all
+       guarded code.
+       * testsuite/21_strings/capacity.cc: Remove reference to __USE_MALLOC.
+       Add documentation on GLIBCPP_FORCE_NEW environment variable.
+       * testsuite/ext/allocators.cc: Likewise.
+
 2002-12-05  Paolo Carlini  <pcarlini@unitus.it>
             Nathan Myers  <ncm@cantrip.org>
 
index f82002acd51352e61e0b9528d0e2037934793208..8f7793fca4e7c241e796358585a6b187223b1f36 100644 (file)
@@ -204,8 +204,6 @@ GLIBCPP_3.2.1 {
   _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_;
   _ZStplIwSt11char_traitsIwESaIwEESbIT_T0_T1_ERKS6_S8_;
 
-  _ZNSt24__default_alloc_templateILb1ELi0EE12_S_force_newE;
-
   # stub functions from libmath
   sinf;
   sinl;
@@ -242,6 +240,12 @@ GLIBCPP_3.2.1 {
 
 } GLIBCPP_3.2;
 
+GLIBCPP_3.2.2 {
+
+  _ZNSt24__default_alloc_templateILb1ELi0EE12_S_force_newE;
+
+} GLIBCPP_3.2.1;
+
 # Symbols in the support library (libsupc++) have their own tag.
 CXXABI_1.2 {
 
index 1c1e137b67c944003277a40deeff2ae512bef106..27314fbafc3daf247ff04ac6f637d9c36f560f1f 100644 (file)
@@ -1,4 +1,9 @@
-<html>
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html
+          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
       solution would probably be more trouble than it's worth.
    </p>
    <p>The STL implementation is currently configured to use the
-      high-speed caching memory allocator.  If you absolutely think
-      you must change this on a global basis for your platform to better
-      support multi-threading, then please consult all commentary in
-      include/bits/stl_alloc.h and the allocators link below.
+      high-speed caching memory allocator.  Some people like to
+      test and/or normally run threaded programs with a different
+      default.  For all details about how to globally override this
+      at application run-time see <a href="../ext/howto.html#3">here</a>.
    </p> 
-   <blockquote>
-      <p>(Explicit warning since so many people get confused while
-      attempting this:)
-      </p>
-      <p><strong>Adding -D__USE_MALLOC on the command
-      line is almost certainly a bad idea.</strong>  Memory efficiency is
-      almost guaranteed to suffer as a result; this is
-      <a href="http://gcc.gnu.org/ml/libstdc++/2001-05/msg00136.html">why
-      we disabled it for 3.0 in the first place</a>.
-      </p>
-      <p>Related to threading or otherwise, the current recommendation is
-      that users not add any macro defines on the command line to remove or
-      otherwise disable features of libstdc++-v3.  There is
-      no condition under which it will help you without causing other
-      issues to perhaps raise up (possible linkage/ABI problems).  In
-      particular, __USE_MALLOC should only be added to a libstdc++-v3
-      configuration file, include/bits/c++config (where such user
-      action is cautioned against), and the entire library should be
-      rebuilt.  If you do not, then you might be violating the
-      one-definition rule of C/C++ and you might cause yourself untold
-      problems.
-      </p>
-   </blockquote>
-   <p>If you find any platform where gcc reports a
-      threading model other than single, and where libstdc++-v3 builds
-      a buggy container allocator when used with threads unless you
-      define __USE_MALLOC, we want to hear about it ASAP.  In the
-      past, correctness was the main reason people were led to believe
-      that they should define __USE_MALLOC when using threads.
-   </p>
    <p>There is a better way (not standardized yet):  It is possible to
       force the malloc-based allocator on a per-case-basis for some
       application code.  The library team generally believes that this
index b4f6dae6f146e0063d292ef14a4947ae781b1992..3d08c5703854a540d1eba2f87ef15de4322e7aa4 100644 (file)
@@ -1,4 +1,9 @@
-<html>
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html
+          PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
          same as <code>allocator&lt;T&gt;</code>.
      </li>
    </ul>
-   <p>An internal typedef, <code> __mem_interface </code>, is defined to be
-      <code>__new_alloc</code> by default.
-   </p>
    <p>Normally,
       <code> __default_alloc_template&lt;bool thr, int inst&gt; </code>
       is also available.  This is the high-speed pool, called the default
       node allocator.  The reusable memory is shared among identical
       instantiations of
-      this type.  It calls through <code>__mem_interface</code> to obtain
+      this type.  It calls through <code>__new_alloc</code> to obtain
       new memory when its lists run out.  If a client container requests a
       block larger than a certain threshold size, then the pool is bypassed,
       and the allocate/deallocate request is passed to
-      <code>__mem_interface</code> directly.
+      <code>__new_alloc</code> directly.
    </p>
    <p>Its <code>inst</code> parameter is described below.  The
       <code>thr</code> boolean determines whether the pool should be
    </p>
    <h3>A cannon to swat a fly:<code>  __USE_MALLOC</code></h3>
    <p>If you've already read <a href="../23_containers/howto.html#3">this
-      advice</a> and decided to define this macro, then the situation changes
-      thusly:
-   </p>
-   <ol>
-     <li><code>__mem_interface</code>, and</li>
-     <li><code>__alloc</code>, and</li>
-     <li><code>__single_client_alloc</code> are all typedef'd to
-         <code>__malloc_alloc_template</code>.</li>
-     <li><code>__default_alloc_template</code> is no longer available.
-         At all.  Anywhere.</li>
-   </ol>
+      advice</a> but still think you remember how to use this macro from
+      SGI STL days.  We have removed it in gcc 3.3.  See next section
+      for the new way to get the same effect.
+   </p>
+   <h3>Globally disabling memory caching:<code>  GLIBCPP_FORCE_NEW</code></h3>
+   <p>Starting with gcc 3.3, if you want to globally disable memory
+      caching within the library for the default allocator (i.e.
+      the one you get for all library objects when you do not specify
+      which one to use), merely set GLIBCPP_FORCE_NEW (at this time,
+      with any value) into your environment before running the
+      program.  You will obtain a similar effect without having to
+      recompile your entire program and the entire library (the new
+      operator in gcc is a light wrapper around malloc).  If your
+      program crashes with GLIBCPP_FORCE_NEW in the environment,
+      it likely means that you linked against objects built against
+      the older library.  Code to support this extension is fully
+      compatible with 3.2 code if GLIBCPP_FORCE_NEW is not in the
+      environment.
+   </p>
    <h3>Writing your own allocators</h3>
    <p>Depending on your application (a specific program, a generic library,
       etc), allocator classes tend to be one of two styles:  &quot;SGI&quot;
index 4344a1d902c9a6ac7ea5e28686374c282c34158d..9482e4cfebad287bc793c34e6a81366a21b081af 100644 (file)
@@ -53,10 +53,6 @@ using std::__debug_alloc;
 using std::__alloc; 
 using std::__single_client_alloc; 
 using std::allocator;
-#ifdef __USE_MALLOC
-using std::malloc_alloc; 
-#else
 using std::__default_alloc_template; 
-#endif
 
 #endif 
index 61a49df308c613e17909d9eb391e0b7cd3e83d46..6f2b7e2db9ceb2589c68d36533e63b9fa7fd7915 100644 (file)
 // so, please report any possible issues to libstdc++@gcc.gnu.org .
 // Do not define __USE_MALLOC on the command line.  Enforce it here:
 #ifdef __USE_MALLOC
-#error __USE_MALLOC should only be defined within \
-libstdc++-v3/include/bits/c++config before full recompilation of the library.
+#error __USE_MALLOC should never be defined.  Read the release notes.
 #endif
-// Define __USE_MALLOC after this point in the file in order to aid debugging
-// or globally change allocation policy.  This breaks the ABI, thus
-// completely recompile the library.  A patch to better support
-// changing the global allocator policy would be probably be accepted.
 
 // The remainder of the prewritten config is mostly automatic; all the
 // user hooks are listed above.
index 7c34000401c13efd68af4270af06a91cf6dbdb76..238986d7eeb685e3651c0acb3c2d39521f798d53 100644 (file)
  *  into a "standard" one.
  *  @endif
  *
+ *  @note The @c reallocate member functions have been deprecated for 3.2
+ *        and will be removed in 3.4.  You must define @c _GLIBCPP_DEPRECATED
+ *        to make this visible in 3.2; see c++config.h.
+ *
  *  The canonical description of these classes is in docs/html/ext/howto.html
  *  or online at http://gcc.gnu.org/onlinedocs/libstdc++/ext/howto.html#3
 */
@@ -85,6 +89,8 @@
 #include <bits/functexcept.h>   // For __throw_bad_alloc
 #include <bits/stl_threads.h>
 
+#include <bits/atomicity.h>
+
 namespace std
 {
   /**
@@ -94,19 +100,19 @@ namespace std
    *  reallocate().
    *  @endif
    *  (See @link Allocators allocators info @endlink for more.)
-  */
-  class __new_alloc 
+   */
+  class __new_alloc
   {
   public:
-    static void* 
+    static void*
     allocate(size_t __n)
     { return ::operator new(__n); }
-    
-    static void 
+
+    static void
     deallocate(void* __p, size_t)
     { ::operator delete(__p); }
   };
-  
+
 
   /**
    *  @if maint
@@ -117,121 +123,134 @@ namespace std
    *  for caveats).  "SGI" style, plus __set_malloc_handler for OOM conditions.
    *  @endif
    *  (See @link Allocators allocators info @endlink for more.)
-  */
-  template <int __inst>
-    class __malloc_alloc_template 
+   */
+  template<int __inst>
+    class __malloc_alloc_template
     {
     private:
       static void* _S_oom_malloc(size_t);
+
+      // _GLIBCPP_DEPRECATED
       static void* _S_oom_realloc(void*, size_t);
+
       static void (* __malloc_alloc_oom_handler)();
-      
+
     public:
-      static void* 
+      static void*
       allocate(size_t __n)
       {
-       void* __result = malloc(__n);
-       if (0 == __result) __result = _S_oom_malloc(__n);
-       return __result;
+        void* __result = malloc(__n);
+        if (__builtin_expect(__result == 0, 0))
+         __result = _S_oom_malloc(__n);
+        return __result;
       }
 
-      static void 
+      static void
       deallocate(void* __p, size_t /* __n */)
       { free(__p); }
 
-      static void* 
+      // _GLIBCPP_DEPRECATED
+      static void*
       reallocate(void* __p, size_t /* old_sz */, size_t __new_sz)
       {
-       void* __result = realloc(__p, __new_sz);
-       if (0 == __result) __result = _S_oom_realloc(__p, __new_sz);
-       return __result;
+        void* __result = realloc(__p, __new_sz);
+        if (__builtin_expect(__result == 0, 0))
+          __result = _S_oom_realloc(__p, __new_sz);
+        return __result;
       }
-      
+
       static void (* __set_malloc_handler(void (*__f)()))()
       {
-       void (* __old)() = __malloc_alloc_oom_handler;
-       __malloc_alloc_oom_handler = __f;
-       return(__old);
+        void (* __old)() = __malloc_alloc_oom_handler;
+        __malloc_alloc_oom_handler = __f;
+        return __old;
       }
     };
 
   // malloc_alloc out-of-memory handling
-  template <int __inst>
+  template<int __inst>
     void (* __malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = 0;
 
-  template <int __inst>
+  template<int __inst>
     void*
-    __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n)
+    __malloc_alloc_template<__inst>::
+    _S_oom_malloc(size_t __n)
     {
       void (* __my_malloc_handler)();
       void* __result;
-      
-      for (;;) 
-       {
-         __my_malloc_handler = __malloc_alloc_oom_handler;
-         if (0 == __my_malloc_handler) 
-           std::__throw_bad_alloc();
-         (*__my_malloc_handler)();
-         __result = malloc(__n);
-         if (__result) 
-           return(__result);
-       }
+
+      for (;;)
+        {
+          __my_malloc_handler = __malloc_alloc_oom_handler;
+          if (__builtin_expect(__my_malloc_handler == 0, 0))
+            __throw_bad_alloc();
+          (*__my_malloc_handler)();
+          __result = malloc(__n);
+          if (__result)
+            return __result;
+        }
     }
-  
-  template <int __inst>
-    void* 
-    __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n)
-    { 
+
+  // _GLIBCPP_DEPRECATED
+  template<int __inst>
+    void*
+    __malloc_alloc_template<__inst>::
+    _S_oom_realloc(void* __p, size_t __n)
+    {
       void (* __my_malloc_handler)();
       void* __result;
-      
-      for (;;) 
-       {
-         __my_malloc_handler = __malloc_alloc_oom_handler;
-         if (0 == __my_malloc_handler) 
-           std::__throw_bad_alloc();
-         (*__my_malloc_handler)();
-         __result = realloc(__p, __n);
-         if (__result) 
-           return(__result);
-       }
-    }
 
+      for (;;)
+        {
+          __my_malloc_handler = __malloc_alloc_oom_handler;
+          if (__builtin_expect(__my_malloc_handler == 0, 0))
+            __throw_bad_alloc();
+          (*__my_malloc_handler)();
+          __result = realloc(__p, __n);
+          if (__result)
+            return __result;
+        }
+    }
 
-// Determines the underlying allocator choice for the node allocator.
-#ifdef __USE_MALLOC
-  typedef __malloc_alloc_template<0>  __mem_interface;
-#else
+  // Should not be referenced within the library anymore.
   typedef __new_alloc                 __mem_interface;
-#endif
-
 
   /**
    *  @if maint
    *  This is used primarily (only?) in _Alloc_traits and other places to
-   *  help provide the _Alloc_type typedef.
+   *  help provide the _Alloc_type typedef.  All it does is forward the
+   *  requests after some minimal checking.
    *
    *  This is neither "standard"-conforming nor "SGI".  The _Alloc parameter
    *  must be "SGI" style.
    *  @endif
    *  (See @link Allocators allocators info @endlink for more.)
-  */
-  template<class _Tp, class _Alloc>
-  class __simple_alloc
-  {
-  public:
-    static _Tp* allocate(size_t __n)
-    { return 0 == __n ? 0 : (_Tp*) _Alloc::allocate(__n * sizeof (_Tp)); }
-
-    static _Tp* allocate()
-    { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
-
-    static void deallocate(_Tp* __p, size_t __n)
-    { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
-
-    static void deallocate(_Tp* __p)
-    { _Alloc::deallocate(__p, sizeof (_Tp)); }
-  };
+   */
+  template<typename _Tp, typename _Alloc>
+    class __simple_alloc
+    {
+    public:
+      static _Tp*
+      allocate(size_t __n)
+      {
+       _Tp* __ret = 0;
+       if (__n)
+         __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+       return __ret;
+      }
+  
+      static _Tp*
+      allocate()
+      { return (_Tp*) _Alloc::allocate(sizeof (_Tp)); }
+  
+      static void
+      deallocate(_Tp* __p, size_t __n)
+      { if (0 != __n) _Alloc::deallocate(__p, __n * sizeof (_Tp)); }
+  
+      static void
+      deallocate(_Tp* __p)
+      { _Alloc::deallocate(__p, sizeof (_Tp)); }
+    };
 
 
   /**
@@ -247,273 +266,290 @@ namespace std
    *  This adaptor is "SGI" style.  The _Alloc parameter must also be "SGI".
    *  @endif
    *  (See @link Allocators allocators info @endlink for more.)
-  */
-  template <class _Alloc>
-  class __debug_alloc
-  {
-  private:
-    enum {_S_extra = 8};  // Size of space used to store size.  Note that this
-                          // must be large enough to preserve alignment.
-  
-  public:
-  
-    static void* allocate(size_t __n)
-    {
-      char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
-      *(size_t*)__result = __n;
-      return __result + (int) _S_extra;
-    }
-  
-    static void deallocate(void* __p, size_t __n)
+   */
+  template<typename _Alloc>
+    class __debug_alloc
     {
-      char* __real_p = (char*)__p - (int) _S_extra;
-      assert(*(size_t*)__real_p == __n);
-      _Alloc::deallocate(__real_p, __n + (int) _S_extra);
-    }
-  
-    static void* reallocate(void* __p, size_t __old_sz, size_t __new_sz)
+    private:
+      // Size of space used to store size.  Note that this must be
+      // large enough to preserve alignment.
+      enum {_S_extra = 8};
+
+    public:
+      static void*
+      allocate(size_t __n)
+      {
+        char* __result = (char*)_Alloc::allocate(__n + (int) _S_extra);
+        *(size_t*)__result = __n;
+        return __result + (int) _S_extra;
+      }
+
+      static void
+      deallocate(void* __p, size_t __n)
+      {
+        char* __real_p = (char*)__p - (int) _S_extra;
+        assert(*(size_t*)__real_p == __n);
+        _Alloc::deallocate(__real_p, __n + (int) _S_extra);
+      }
+
+      // _GLIBCPP_DEPRECATED
+      static void*
+      reallocate(void* __p, size_t __old_sz, size_t __new_sz)
+      {
+        char* __real_p = (char*)__p - (int) _S_extra;
+        assert(*(size_t*)__real_p == __old_sz);
+        char* __result = (char*) _Alloc::reallocate(__real_p, 
+                                                   __old_sz + (int) _S_extra,
+                                                   __new_sz + (int) _S_extra);
+        *(size_t*)__result = __new_sz;
+        return __result + (int) _S_extra;
+      }
+    };
+
+
+  /**
+   *  @if maint
+   *  Default node allocator.  "SGI" style.  Uses various allocators to
+   *  fulfill underlying requests (and makes as few requests as possible
+   *  when in default high-speed pool mode).
+   *
+   *  Important implementation properties:
+   *  0. If globally mandated, then allocate objects from __new_alloc
+   *  1. If the clients request an object of size > _MAX_BYTES, the resulting
+   *     object will be obtained directly from __new_alloc
+   *  2. In all other cases, we allocate an object of size exactly
+   *     _S_round_up(requested_size).  Thus the client has enough size
+   *     information that we can return the object to the proper free list
+   *     without permanently losing part of the object.
+   *
+   *  The first template parameter specifies whether more than one thread may
+   *  use this allocator.  It is safe to allocate an object from one instance
+   *  of a default_alloc and deallocate it with another one.  This effectively
+   *  transfers its ownership to the second one.  This may have undesirable
+   *  effects on reference locality.
+   *
+   *  The second parameter is unused and serves only to allow the creation of
+   *  multiple default_alloc instances.  Note that containers built on different
+   *  allocator instances have different types, limiting the utility of this
+   *  approach.  If you do not wish to share the free lists with the main
+   *  default_alloc instance, instantiate this with a non-zero __inst.
+   *
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<bool __threads, int __inst>
+    class __default_alloc_template
     {
-      char* __real_p = (char*)__p - (int) _S_extra;
-      assert(*(size_t*)__real_p == __old_sz);
-      char* __result = (char*)
-        _Alloc::reallocate(__real_p, __old_sz + (int) _S_extra,
-                                     __new_sz + (int) _S_extra);
-      *(size_t*)__result = __new_sz;
-      return __result + (int) _S_extra;
-    }
-  };
+    private:
+      enum {_ALIGN = 8};
+      enum {_MAX_BYTES = 128};
+      enum {_NFREELISTS = _MAX_BYTES / _ALIGN};
 
+      union _Obj
+      {
+        union _Obj* _M_free_list_link;
+        char        _M_client_data[1];    // The client sees this.
+      };
 
-#ifdef __USE_MALLOC
+      static _Obj* volatile         _S_free_list[_NFREELISTS];
 
-typedef __mem_interface __alloc;
-typedef __mem_interface __single_client_alloc;
+      // Chunk allocation state.
+      static char*                  _S_start_free;
+      static char*                  _S_end_free;
+      static size_t                 _S_heap_size;
 
-#else
+      static _STL_mutex_lock        _S_node_allocator_lock;
 
+      static size_t
+      _S_round_up(size_t __bytes)
+      { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }
 
-/**
- *  @if maint
- *  Default node allocator.  "SGI" style.  Uses __mem_interface for its
- *  underlying requests (and makes as few requests as possible).
- *  **** Currently __mem_interface is always __new_alloc, never __malloc*.
- * 
- *  Important implementation properties:
- *  1. If the clients request an object of size > _MAX_BYTES, the resulting
- *     object will be obtained directly from the underlying __mem_interface.
- *  2. In all other cases, we allocate an object of size exactly
- *     _S_round_up(requested_size).  Thus the client has enough size
- *     information that we can return the object to the proper free list
- *     without permanently losing part of the object.
- * 
- *  The first template parameter specifies whether more than one thread may
- *  use this allocator.  It is safe to allocate an object from one instance
- *  of a default_alloc and deallocate it with another one.  This effectively
- *  transfers its ownership to the second one.  This may have undesirable
- *  effects on reference locality.
- *
- *  The second parameter is unused and serves only to allow the creation of
- *  multiple default_alloc instances.  Note that containers built on different
- *  allocator instances have different types, limiting the utility of this
- *  approach.  If you do not wish to share the free lists with the main
- *  default_alloc instance, instantiate this with a non-zero __inst.
- *
- *  @endif
- *  (See @link Allocators allocators info @endlink for more.)
-*/
-template<bool __threads, int __inst>
-  class __default_alloc_template
-  {
-  private:
-    enum {_ALIGN = 8};
-    enum {_MAX_BYTES = 128};
-    enum {_NFREELISTS = _MAX_BYTES / _ALIGN};
-    
-    union _Obj 
-    {
-      union _Obj* _M_free_list_link;
-      char        _M_client_data[1];    // The client sees this.
-    };
+      static size_t
+      _S_freelist_index(size_t __bytes)
+      { return (((__bytes) + (size_t)_ALIGN - 1)/(size_t)_ALIGN - 1); }
+
+      // Returns an object of size __n, and optionally adds to size __n
+      // free list.
+      static void*
+      _S_refill(size_t __n);
+
+      // Allocates a chunk for nobjs of size size.  nobjs may be reduced
+      // if it is inconvenient to allocate the requested number.
+      static char*
+      _S_chunk_alloc(size_t __size, int& __nobjs);
+
+      // It would be nice to use _STL_auto_lock here.  But we need a
+      // test whether threads are in use.
+      struct _Lock
+      {
+        _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); }
+        ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); }
+      } __attribute__ ((__unused__));
+      friend struct _Lock;
+
+      static _Atomic_word _S_force_new;
 
-    static _Obj* volatile      _S_free_list[_NFREELISTS]; 
-
-    // Chunk allocation state.
-    static char*               _S_start_free;
-    static char*               _S_end_free;
-    static size_t              _S_heap_size;
-    
-    static _STL_mutex_lock     _S_node_allocator_lock;
-
-    static size_t
-    _S_round_up(size_t __bytes) 
-    { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }
-
-    static size_t 
-    _S_freelist_index(size_t __bytes)
-    { return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1); }
-
-    // Returns an object of size __n, and optionally adds to size __n
-    // free list.
-    static void* 
-    _S_refill(size_t __n);
-
-    // Allocates a chunk for nobjs of size size.  nobjs may be reduced
-    // if it is inconvenient to allocate the requested number.
-    static char* 
-    _S_chunk_alloc(size_t __size, int& __nobjs);
-    
-    // It would be nice to use _STL_auto_lock here.  But we need a
-    // test whether threads are in use.
-    class _Lock 
-    {
     public:
-      _Lock() { if (__threads) _S_node_allocator_lock._M_acquire_lock(); }
-      ~_Lock() { if (__threads) _S_node_allocator_lock._M_release_lock(); }
-    } __attribute__ ((__unused__));
-    friend class _Lock;
-    
-  public:
-    // __n must be > 0
-    static void* 
-    allocate(size_t __n)
-    {
-      void* __ret = 0;
-      
-      if (__n > (size_t) _MAX_BYTES) 
-       __ret = __mem_interface::allocate(__n);
-      else 
-       {
-         _Obj* volatile* __my_free_list = _S_free_list 
-           + _S_freelist_index(__n);
-         // Acquire the lock here with a constructor call.  This
-         // ensures that it is released in exit or during stack
-         // unwinding.
-         _Lock __lock_instance;
-         _Obj* __restrict__ __result = *__my_free_list;
-         if (__result == 0)
-           __ret = _S_refill(_S_round_up(__n));
-         else 
-           {
-             *__my_free_list = __result -> _M_free_list_link;
-             __ret = __result;
-           }
-       }
-      return __ret;
-    };
+      // __n must be > 0
+      static void*
+      allocate(size_t __n)
+      {
+       void* __ret = 0;
+
+       // If there is a race through here, assume answer from getenv
+       // will resolve in same direction.  Inspired by techniques
+       // to efficiently support threading found in basic_string.h.
+       if (_S_force_new == 0)
+         {
+           if (getenv("GLIBCPP_FORCE_NEW"))
+             __atomic_add(&_S_force_new, 1);
+           else
+             __atomic_add(&_S_force_new, -1);
+           // Trust but verify...
+           assert(_S_force_new != 0);
+         }
+
+       if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
+         __ret = __new_alloc::allocate(__n);
+       else
+         {
+           _Obj* volatile* __my_free_list = _S_free_list
+             + _S_freelist_index(__n);
+           // Acquire the lock here with a constructor call.  This
+           // ensures that it is released in exit or during stack
+           // unwinding.
+           _Lock __lock_instance;
+           _Obj* __restrict__ __result = *__my_free_list;
+           if (__builtin_expect(__result == 0, 0))
+             __ret = _S_refill(_S_round_up(__n));
+           else
+             {
+               *__my_free_list = __result -> _M_free_list_link;
+               __ret = __result;
+             }     
+           if (__builtin_expect(__ret == 0, 0))
+             __throw_bad_alloc();
+         }
+       return __ret;
+      }
 
-    // __p may not be 0
-    static void 
-    deallocate(void* __p, size_t __n)
-    {
-      if (__n > (size_t) _MAX_BYTES)
-       __mem_interface::deallocate(__p, __n);
-      else 
-       {
-         _Obj* volatile*  __my_free_list
-           = _S_free_list + _S_freelist_index(__n);
-         _Obj* __q = (_Obj*)__p;
-         
-         // Acquire the lock here with a constructor call.  This ensures that
-         // it is released in exit or during stack unwinding.
-         _Lock __lock_instance;
-         __q -> _M_free_list_link = *__my_free_list;
-         *__my_free_list = __q;
-       }
-    }
-    
-    static void* 
-    reallocate(void* __p, size_t __old_sz, size_t __new_sz);
-  };
+      // __p may not be 0
+      static void
+      deallocate(void* __p, size_t __n)
+      {
+       if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
+         __new_alloc::deallocate(__p, __n);
+       else
+         {
+           _Obj* volatile*  __my_free_list = _S_free_list
+             + _S_freelist_index(__n);
+           _Obj* __q = (_Obj*)__p;
+
+           // Acquire the lock here with a constructor call.  This
+           // ensures that it is released in exit or during stack
+           // unwinding.
+           _Lock __lock_instance;
+           __q -> _M_free_list_link = *__my_free_list;
+           *__my_free_list = __q;
+         }
+      }
+
+      // _GLIBCPP_DEPRECATED
+      static void*
+      reallocate(void* __p, size_t __old_sz, size_t __new_sz);
+    };
 
+  template<bool __threads, int __inst> _Atomic_word
+  __default_alloc_template<__threads, __inst>::_S_force_new = 0;
 
   template<bool __threads, int __inst>
-    inline bool 
-    operator==(const __default_alloc_template<__threads, __inst>&,
-              const __default_alloc_template<__threads, __inst>&)
+    inline bool
+    operator==(const __default_alloc_template<__threads,__inst>&,
+               const __default_alloc_template<__threads,__inst>&)
     { return true; }
 
   template<bool __threads, int __inst>
-    inline bool 
-    operator!=(const __default_alloc_template<__threads, __inst>&,
-              const __default_alloc_template<__threads, __inst>&)
+    inline bool
+    operator!=(const __default_alloc_template<__threads,__inst>&,
+               const __default_alloc_template<__threads,__inst>&)
     { return false; }
 
 
   // We allocate memory in large chunks in order to avoid fragmenting the
-  // malloc heap (or whatever __mem_interface is using) too much.  We assume
-  // that __size is properly aligned.  We hold the allocation lock.
+  // heap too much.  We assume that __size is properly aligned.  We hold
+  // the allocation lock.
   template<bool __threads, int __inst>
     char*
-    __default_alloc_template<__threads, __inst>::_S_chunk_alloc(size_t __size, 
-                                                               int& __nobjs)
+    __default_alloc_template<__threads, __inst>::
+    _S_chunk_alloc(size_t __size, int& __nobjs)
     {
       char* __result;
       size_t __total_bytes = __size * __nobjs;
       size_t __bytes_left = _S_end_free - _S_start_free;
-      
-      if (__bytes_left >= __total_bytes) 
-      {
-        __result = _S_start_free;
-        _S_start_free += __total_bytes;
-        return(__result);
-      } 
-      else if (__bytes_left >= __size) 
-       {
-         __nobjs = (int)(__bytes_left/__size);
-         __total_bytes = __size * __nobjs;
-         __result = _S_start_free;
-         _S_start_free += __total_bytes;
-         return(__result);
-       } 
-      else 
-       {
-         size_t __bytes_to_get = 
-           2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
-         // Try to make use of the left-over piece.
-         if (__bytes_left > 0) 
-           {
-             _Obj* volatile* __my_free_list =
-               _S_free_list + _S_freelist_index(__bytes_left);
-             
-             ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
-             *__my_free_list = (_Obj*)_S_start_free;
-           }
-         _S_start_free = (char*) __mem_interface::allocate(__bytes_to_get);
-         if (0 == _S_start_free) 
-           {
-             size_t __i;
-             _Obj* volatile* __my_free_list;
-             _Obj* __p;
-             // Try to make do with what we have.  That can't hurt.  We
-             // do not try smaller requests, since that tends to result
-             // in disaster on multi-process machines.
-             __i = __size;
-             for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN) 
-               {
-                 __my_free_list = _S_free_list + _S_freelist_index(__i);
-                 __p = *__my_free_list;
-                 if (0 != __p) 
-                   {
-                     *__my_free_list = __p -> _M_free_list_link;
-                     _S_start_free = (char*)__p;
-                     _S_end_free = _S_start_free + __i;
-                     return(_S_chunk_alloc(__size, __nobjs));
-                     // Any leftover piece will eventually make it to the
-                     // right free list.
-                   }
-               }
-             _S_end_free = 0;  // In case of exception.
-             _S_start_free = (char*)__mem_interface::allocate(__bytes_to_get);
-             // This should either throw an exception or remedy the situation.
-             // Thus we assume it succeeded.
-           }
-         _S_heap_size += __bytes_to_get;
-         _S_end_free = _S_start_free + __bytes_to_get;
-         return(_S_chunk_alloc(__size, __nobjs));
-       }
+
+      if (__bytes_left >= __total_bytes)
+        {
+          __result = _S_start_free;
+          _S_start_free += __total_bytes;
+          return __result ;
+        }
+      else if (__bytes_left >= __size)
+        {
+          __nobjs = (int)(__bytes_left/__size);
+          __total_bytes = __size * __nobjs;
+          __result = _S_start_free;
+          _S_start_free += __total_bytes;
+          return __result;
+        }
+      else
+        {
+          size_t __bytes_to_get =
+            2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
+          // Try to make use of the left-over piece.
+          if (__bytes_left > 0)
+            {
+              _Obj* volatile* __my_free_list =
+                _S_free_list + _S_freelist_index(__bytes_left);
+
+              ((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
+              *__my_free_list = (_Obj*)_S_start_free;
+            }
+          _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
+          if (_S_start_free == 0)
+            {
+              size_t __i;
+              _Obj* volatile* __my_free_list;
+              _Obj* __p;
+              // Try to make do with what we have.  That can't hurt.  We
+              // do not try smaller requests, since that tends to result
+              // in disaster on multi-process machines.
+              __i = __size;
+              for (; __i <= (size_t) _MAX_BYTES; __i += (size_t) _ALIGN)
+                {
+                  __my_free_list = _S_free_list + _S_freelist_index(__i);
+                  __p = *__my_free_list;
+                  if (__p != 0)
+                    {
+                      *__my_free_list = __p -> _M_free_list_link;
+                      _S_start_free = (char*)__p;
+                      _S_end_free = _S_start_free + __i;
+                      return _S_chunk_alloc(__size, __nobjs);
+                      // Any leftover piece will eventually make it to the
+                      // right free list.
+                    }
+                }
+              _S_end_free = 0;        // In case of exception.
+              _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
+              // This should either throw an exception or remedy the situation.
+              // Thus we assume it succeeded.
+            }
+          _S_heap_size += __bytes_to_get;
+          _S_end_free = _S_start_free + __bytes_to_get;
+          return _S_chunk_alloc(__size, __nobjs);
+        }
     }
-  
-  
+
+
   // Returns an object of size __n, and optionally adds to "size
   // __n"'s free list.  We assume that __n is properly aligned.  We
   // hold the allocation lock.
@@ -528,414 +564,421 @@ template<bool __threads, int __inst>
       _Obj* __current_obj;
       _Obj* __next_obj;
       int __i;
-      
-      if (1 == __nobjs) return(__chunk);
+
+      if (1 == __nobjs)
+        return __chunk;
       __my_free_list = _S_free_list + _S_freelist_index(__n);
-      
-      /* Build free list in chunk */
+
+      // Build free list in chunk.
       __result = (_Obj*)__chunk;
       *__my_free_list = __next_obj = (_Obj*)(__chunk + __n);
-      for (__i = 1; ; __i++) {
-        __current_obj = __next_obj;
-        __next_obj = (_Obj*)((char*)__next_obj + __n);
-        if (__nobjs - 1 == __i) {
-         __current_obj -> _M_free_list_link = 0;
-         break;
-        } else {
-         __current_obj -> _M_free_list_link = __next_obj;
-        }
-      }
-      return(__result);
+      for (__i = 1; ; __i++)
+        {
+         __current_obj = __next_obj;
+          __next_obj = (_Obj*)((char*)__next_obj + __n);
+         if (__nobjs - 1 == __i)
+           {
+             __current_obj -> _M_free_list_link = 0;
+             break;
+           }
+         else
+           __current_obj -> _M_free_list_link = __next_obj;
+       }
+      return __result;
     }
 
 
+  // _GLIBCPP_DEPRECATED
   template<bool threads, int inst>
     void*
-    __default_alloc_template<threads, inst>::reallocate(void* __p, 
-                                                       size_t __old_sz,
-                                                       size_t __new_sz)
+    __default_alloc_template<threads, inst>::
+    reallocate(void* __p, size_t __old_sz, size_t __new_sz)
     {
       void* __result;
       size_t __copy_sz;
-      
-      if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES) {
+
+      if (__old_sz > (size_t) _MAX_BYTES && __new_sz > (size_t) _MAX_BYTES)
         return(realloc(__p, __new_sz));
-      }
-      if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) return(__p);
+      if (_S_round_up(__old_sz) == _S_round_up(__new_sz))
+        return(__p);
       __result = allocate(__new_sz);
       __copy_sz = __new_sz > __old_sz? __old_sz : __new_sz;
       memcpy(__result, __p, __copy_sz);
       deallocate(__p, __old_sz);
-      return(__result);
+      return __result;
     }
-  
+
   template<bool __threads, int __inst>
-  _STL_mutex_lock
-  __default_alloc_template<__threads, __inst>::_S_node_allocator_lock
-  __STL_MUTEX_INITIALIZER;
-  
+    _STL_mutex_lock
+    __default_alloc_template<__threads,__inst>::_S_node_allocator_lock
+    __STL_MUTEX_INITIALIZER;
+
   template<bool __threads, int __inst>
-  char* __default_alloc_template<__threads, __inst>::_S_start_free = 0;
-  
+    char* __default_alloc_template<__threads,__inst>::_S_start_free = 0;
+
   template<bool __threads, int __inst>
-  char* __default_alloc_template<__threads, __inst>::_S_end_free = 0;
-  
+    char* __default_alloc_template<__threads,__inst>::_S_end_free = 0;
+
   template<bool __threads, int __inst>
-  size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0;
-  
+    size_t __default_alloc_template<__threads,__inst>::_S_heap_size = 0;
+
   template<bool __threads, int __inst>
-  typename __default_alloc_template<__threads, __inst>::_Obj* volatile
-  __default_alloc_template<__threads, __inst>::_S_free_list[_NFREELISTS];
-  
-  typedef __default_alloc_template<true, 0>    __alloc;
-  typedef __default_alloc_template<false, 0>   __single_client_alloc;
+    typename __default_alloc_template<__threads,__inst>::_Obj* volatile
+    __default_alloc_template<__threads,__inst>::_S_free_list[_NFREELISTS];
 
+  typedef __default_alloc_template<true,0>    __alloc;
+  typedef __default_alloc_template<false,0>   __single_client_alloc;
 
-#endif /* ! __USE_MALLOC */
 
+  /**
+   *  @brief  The "standard" allocator, as per [20.4].
+   *
+   *  The private _Alloc is "SGI" style.  (See comments at the top
+   *  of stl_alloc.h.)
+   *
+   *  The underlying allocator behaves as follows.
+   *    - __default_alloc_template is used via two typedefs
+   *    - "__single_client_alloc" typedef does no locking for threads
+   *    - "__alloc" typedef is threadsafe via the locks
+   *    - __new_alloc is used for memory requests
+   *
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<typename _Tp>
+    class allocator
+    {
+      typedef __alloc _Alloc;          // The underlying allocator.
+    public:
+      typedef size_t     size_type;
+      typedef ptrdiff_t  difference_type;
+      typedef _Tp*       pointer;
+      typedef const _Tp* const_pointer;
+      typedef _Tp&       reference;
+      typedef const _Tp& const_reference;
+      typedef _Tp        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef allocator<_Tp1> other; };
+
+      allocator() throw() {}
+      allocator(const allocator&) throw() {}
+      template<typename _Tp1>
+        allocator(const allocator<_Tp1>&) throw() {}
+      ~allocator() throw() {}
+
+      pointer
+      address(reference __x) const { return &__x; }
+
+      const_pointer
+      address(const_reference __x) const { return &__x; }
+
+      // NB: __n is permitted to be 0.  The C++ standard says nothing
+      // about what the return value is when __n == 0.
+      _Tp*
+      allocate(size_type __n, const void* = 0)
+      {
+       _Tp* __ret = 0;
+       if (__n)
+         {
+           if (__n <= this->max_size())
+             __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+           else
+             __throw_bad_alloc();
+         }
+       return __ret;
+      }
 
-/**
- *  This is a "standard" allocator, as per [20.4].  The private _Alloc is
- *  "SGI" style.  (See comments at the top of stl_alloc.h.)
- *
- *  The underlying allocator behaves as follows.
- *  - if __USE_MALLOC then
- *    - thread safety depends on malloc and is entirely out of our hands
- *    - __malloc_alloc_template is used for memory requests
- *  - else (the default)
- *    - __default_alloc_template is used via two typedefs
- *    - "__single_client_alloc" typedef does no locking for threads
- *    - "__alloc" typedef is threadsafe via the locks
- *    - __new_alloc is used for memory requests
- *
- *  (See @link Allocators allocators info @endlink for more.)
-*/
-template <class _Tp>
-class allocator
-{
-  typedef __alloc _Alloc;          // The underlying allocator.
-public:
-  typedef size_t     size_type;
-  typedef ptrdiff_t  difference_type;
-  typedef _Tp*       pointer;
-  typedef const _Tp* const_pointer;
-  typedef _Tp&       reference;
-  typedef const _Tp& const_reference;
-  typedef _Tp        value_type;
-
-  template <class _Tp1> struct rebind {
-    typedef allocator<_Tp1> other;
-  };
+      // __p is not permitted to be a null pointer.
+      void
+      deallocate(pointer __p, size_type __n)
+      { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
 
-  allocator() throw() {}
-  allocator(const allocator&) throw() {}
-  template <class _Tp1> allocator(const allocator<_Tp1>&) throw() {}
-  ~allocator() throw() {}
-
-  pointer address(reference __x) const { return &__x; }
-  const_pointer address(const_reference __x) const { return &__x; }
-
-  // __n is permitted to be 0.  The C++ standard says nothing about what
-  // the return value is when __n == 0.
-  _Tp* allocate(size_type __n, const void* = 0) {
-    return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) 
-                    : 0;
-  }
-
-  // __p is not permitted to be a null pointer.
-  void deallocate(pointer __p, size_type __n)
-    { _Alloc::deallocate(__p, __n * sizeof(_Tp)); }
-
-  size_type max_size() const throw() 
-    { return size_t(-1) / sizeof(_Tp); }
-
-  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-  void destroy(pointer __p) { __p->~_Tp(); }
-};
-
-template<>
-class allocator<void> {
-public:
-  typedef size_t      size_type;
-  typedef ptrdiff_t   difference_type;
-  typedef void*       pointer;
-  typedef const void* const_pointer;
-  typedef void        value_type;
-
-  template <class _Tp1> struct rebind {
-    typedef allocator<_Tp1> other;
-  };
-};
+      size_type
+      max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
 
+      void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+      void destroy(pointer __p) { __p->~_Tp(); }
+    };
 
-template <class _T1, class _T2>
-inline bool operator==(const allocator<_T1>&, const allocator<_T2>&) 
-{
-  return true;
-}
+  template<>
+    class allocator<void>
+    {
+    public:
+      typedef size_t      size_type;
+      typedef ptrdiff_t   difference_type;
+      typedef void*       pointer;
+      typedef const void* const_pointer;
+      typedef void        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef allocator<_Tp1> other; };
+    };
 
-template <class _T1, class _T2>
-inline bool operator!=(const allocator<_T1>&, const allocator<_T2>&)
-{
-  return false;
-}
 
+  template<typename _T1, typename _T2>
+    inline bool
+    operator==(const allocator<_T1>&, const allocator<_T2>&)
+    { return true; }
 
-/**
- *  @if maint
- *  Allocator adaptor to turn an "SGI" style allocator (e.g., __alloc,
- *  __malloc_alloc_template) into a "standard" conforming allocator.  Note
- *  that this adaptor does *not* assume that all objects of the underlying
- *  alloc class are identical, nor does it assume that all of the underlying
- *  alloc's member functions are static member functions.  Note, also, that
- *  __allocator<_Tp, __alloc> is essentially the same thing as allocator<_Tp>.
- *  @endif
- *  (See @link Allocators allocators info @endlink for more.)
-*/
-template <class _Tp, class _Alloc>
-struct __allocator
-{
-  _Alloc __underlying_alloc;
-
-  typedef size_t    size_type;
-  typedef ptrdiff_t difference_type;
-  typedef _Tp*       pointer;
-  typedef const _Tp* const_pointer;
-  typedef _Tp&       reference;
-  typedef const _Tp& const_reference;
-  typedef _Tp        value_type;
-
-  template <class _Tp1> struct rebind {
-    typedef __allocator<_Tp1, _Alloc> other;
-  };
+  template<typename _T1, typename _T2>
+    inline bool
+    operator!=(const allocator<_T1>&, const allocator<_T2>&)
+    { return false; }
 
-  __allocator() throw() {}
-  __allocator(const __allocator& __a) throw()
-    : __underlying_alloc(__a.__underlying_alloc) {}
-  template <class _Tp1> 
-  __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
-    : __underlying_alloc(__a.__underlying_alloc) {}
-  ~__allocator() throw() {}
-
-  pointer address(reference __x) const { return &__x; }
-  const_pointer address(const_reference __x) const { return &__x; }
-
-  // __n is permitted to be 0.
-  _Tp* allocate(size_type __n, const void* = 0) {
-    return __n != 0 
-        ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) 
-        : 0;
-  }
-
-  // __p is not permitted to be a null pointer.
-  void deallocate(pointer __p, size_type __n)
-    { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
-
-  size_type max_size() const throw() 
-    { return size_t(-1) / sizeof(_Tp); }
-
-  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
-  void destroy(pointer __p) { __p->~_Tp(); }
-};
-
-template <class _Alloc>
-class __allocator<void, _Alloc> {
-  typedef size_t      size_type;
-  typedef ptrdiff_t   difference_type;
-  typedef void*       pointer;
-  typedef const void* const_pointer;
-  typedef void        value_type;
-
-  template <class _Tp1> struct rebind {
-    typedef __allocator<_Tp1, _Alloc> other;
-  };
-};
 
-template <class _Tp, class _Alloc>
-inline bool operator==(const __allocator<_Tp, _Alloc>& __a1,
-                       const __allocator<_Tp, _Alloc>& __a2)
-{
-  return __a1.__underlying_alloc == __a2.__underlying_alloc;
-}
+  /**
+   *  @if maint
+   *  Allocator adaptor to turn an "SGI" style allocator (e.g.,
+   *  __alloc, __malloc_alloc_template) into a "standard" conforming
+   *  allocator.  Note that this adaptor does *not* assume that all
+   *  objects of the underlying alloc class are identical, nor does it
+   *  assume that all of the underlying alloc's member functions are
+   *  static member functions.  Note, also, that __allocator<_Tp,
+   *  __alloc> is essentially the same thing as allocator<_Tp>.
+   *  @endif
+   *  (See @link Allocators allocators info @endlink for more.)
+   */
+  template<typename _Tp, typename _Alloc>
+    struct __allocator
+    {
+      _Alloc __underlying_alloc;
+      
+      typedef size_t    size_type;
+      typedef ptrdiff_t difference_type;
+      typedef _Tp*       pointer;
+      typedef const _Tp* const_pointer;
+      typedef _Tp&       reference;
+      typedef const _Tp& const_reference;
+      typedef _Tp        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef __allocator<_Tp1, _Alloc> other; };
+
+      __allocator() throw() {}
+      __allocator(const __allocator& __a) throw()
+      : __underlying_alloc(__a.__underlying_alloc) {}
+
+      template<typename _Tp1>
+        __allocator(const __allocator<_Tp1, _Alloc>& __a) throw()
+        : __underlying_alloc(__a.__underlying_alloc) {}
+
+      ~__allocator() throw() {}
+
+      pointer
+      address(reference __x) const { return &__x; }
+
+      const_pointer
+      address(const_reference __x) const { return &__x; }
+
+      // NB: __n is permitted to be 0.  The C++ standard says nothing
+      // about what the return value is when __n == 0.
+      _Tp*
+      allocate(size_type __n, const void* = 0)
+      {
+       _Tp* __ret = 0;
+       if (__n)
+         __ret = static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp)));
+       return __ret;
+      }
 
-template <class _Tp, class _Alloc>
-inline bool operator!=(const __allocator<_Tp, _Alloc>& __a1,
-                       const __allocator<_Tp, _Alloc>& __a2)
-{
-  return __a1.__underlying_alloc != __a2.__underlying_alloc;
-}
+      // __p is not permitted to be a null pointer.
+      void
+      deallocate(pointer __p, size_type __n)
+      { __underlying_alloc.deallocate(__p, __n * sizeof(_Tp)); }
+      
+      size_type
+      max_size() const throw() { return size_t(-1) / sizeof(_Tp); }
+      
+      void
+      construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
+      
+      void
+      destroy(pointer __p) { __p->~_Tp(); }
+    };
 
+  template<typename _Alloc>
+    struct __allocator<void, _Alloc>
+    {
+      typedef size_t      size_type;
+      typedef ptrdiff_t   difference_type;
+      typedef void*       pointer;
+      typedef const void* const_pointer;
+      typedef void        value_type;
+
+      template<typename _Tp1>
+        struct rebind
+        { typedef __allocator<_Tp1, _Alloc> other; };
+    };
 
-//@{
-/** Comparison operators for all of the predifined SGI-style allocators.
- *  This ensures that __allocator<malloc_alloc> (for example) will work
- *  correctly.  As required, all allocators compare equal.
-*/
-template <int inst>
-inline bool operator==(const __malloc_alloc_template<inst>&,
-                       const __malloc_alloc_template<inst>&)
-{
-  return true;
-}
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator==(const __allocator<_Tp,_Alloc>& __a1,
+               const __allocator<_Tp,_Alloc>& __a2)
+    { return __a1.__underlying_alloc == __a2.__underlying_alloc; }
+
+  template<typename _Tp, typename _Alloc>
+    inline bool
+    operator!=(const __allocator<_Tp, _Alloc>& __a1,
+               const __allocator<_Tp, _Alloc>& __a2)
+    { return __a1.__underlying_alloc != __a2.__underlying_alloc; }
+
+
+  //@{
+  /** Comparison operators for all of the predifined SGI-style allocators.
+   *  This ensures that __allocator<malloc_alloc> (for example) will work
+   *  correctly.  As required, all allocators compare equal.
+   */
+  template<int inst>
+    inline bool
+    operator==(const __malloc_alloc_template<inst>&,
+               const __malloc_alloc_template<inst>&)
+    { return true; }
 
-template <int __inst>
-inline bool operator!=(const __malloc_alloc_template<__inst>&,
-                       const __malloc_alloc_template<__inst>&)
-{
-  return false;
-}
+  template<int __inst>
+    inline bool
+    operator!=(const __malloc_alloc_template<__inst>&,
+               const __malloc_alloc_template<__inst>&)
+    { return false; }
 
-template <class _Alloc>
-inline bool operator==(const __debug_alloc<_Alloc>&,
-                       const __debug_alloc<_Alloc>&) {
-  return true;
-}
+  template<typename _Alloc>
+    inline bool
+    operator==(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+    { return true; }
 
-template <class _Alloc>
-inline bool operator!=(const __debug_alloc<_Alloc>&,
-                       const __debug_alloc<_Alloc>&) {
-  return false;
-}
-//@}
+  template<typename _Alloc>
+    inline bool
+    operator!=(const __debug_alloc<_Alloc>&, const __debug_alloc<_Alloc>&)
+    { return false; }
+  //@}
 
 
-/**
- *  @if maint
- *  Another allocator adaptor:  _Alloc_traits.  This serves two purposes.
- *  First, make it possible to write containers that can use either "SGI"
- *  style allocators or "standard" allocators.  Second, provide a mechanism
- *  so that containers can query whether or not the allocator has distinct
- *  instances.  If not, the container can avoid wasting a word of memory to
- *  store an empty object.  For examples of use, see stl_vector.h, etc, or
- *  any of the other classes derived from this one.
- *
- *  This adaptor uses partial specialization.  The general case of
- *  _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
- *  standard-conforming allocator, possibly with non-equal instances and
- *  non-static members.  (It still behaves correctly even if _Alloc has
- *  static member and if all instances are equal.  Refinements affect
- *  performance, not correctness.)
- *
- *  There are always two members:  allocator_type, which is a standard-
- *  conforming allocator type for allocating objects of type _Tp, and
- *  _S_instanceless, a static const member of type bool.  If
- *  _S_instanceless is true, this means that there is no difference
- *  between any two instances of type allocator_type.  Furthermore, if
- *  _S_instanceless is true, then _Alloc_traits has one additional
- *  member:  _Alloc_type.  This type encapsulates allocation and
- *  deallocation of objects of type _Tp through a static interface; it
- *  has two member functions, whose signatures are
- *
- *  -  static _Tp* allocate(size_t)
- *  -  static void deallocate(_Tp*, size_t)
- *
- *  The size_t parameters are "standard" style (see top of stl_alloc.h) in
- *  that they take counts, not sizes.
- *
- *  @endif
- *  (See @link Allocators allocators info @endlink for more.)
-*/
-//@{
-// The fully general version.
-template <class _Tp, class _Allocator>
-struct _Alloc_traits
-{
-  static const bool _S_instanceless = false;
-  typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
-};
+  /**
  *  @if maint
  *  Another allocator adaptor:  _Alloc_traits.  This serves two purposes.
  *  First, make it possible to write containers that can use either "SGI"
  *  style allocators or "standard" allocators.  Second, provide a mechanism
  *  so that containers can query whether or not the allocator has distinct
  *  instances.  If not, the container can avoid wasting a word of memory to
  *  store an empty object.  For examples of use, see stl_vector.h, etc, or
  *  any of the other classes derived from this one.
  *
  *  This adaptor uses partial specialization.  The general case of
  *  _Alloc_traits<_Tp, _Alloc> assumes that _Alloc is a
  *  standard-conforming allocator, possibly with non-equal instances and
  *  non-static members.  (It still behaves correctly even if _Alloc has
  *  static member and if all instances are equal.  Refinements affect
  *  performance, not correctness.)
  *
  *  There are always two members:  allocator_type, which is a standard-
  *  conforming allocator type for allocating objects of type _Tp, and
  *  _S_instanceless, a static const member of type bool.  If
  *  _S_instanceless is true, this means that there is no difference
  *  between any two instances of type allocator_type.  Furthermore, if
  *  _S_instanceless is true, then _Alloc_traits has one additional
  *  member:  _Alloc_type.  This type encapsulates allocation and
  *  deallocation of objects of type _Tp through a static interface; it
  *  has two member functions, whose signatures are
  *
  *  -  static _Tp* allocate(size_t)
  *  -  static void deallocate(_Tp*, size_t)
  *
  *  The size_t parameters are "standard" style (see top of stl_alloc.h) in
  *  that they take counts, not sizes.
  *
  *  @endif
  *  (See @link Allocators allocators info @endlink for more.)
+   */
+  //@{
+  // The fully general version.
+  template<typename _Tp, typename _Allocator>
+    struct _Alloc_traits
+    {
+      static const bool _S_instanceless = false;
+      typedef typename _Allocator::template rebind<_Tp>::other allocator_type;
+    };
 
-template <class _Tp, class _Allocator>
-const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
+  template<typename _Tp, typename _Allocator>
+    const bool _Alloc_traits<_Tp, _Allocator>::_S_instanceless;
 
-/// The version for the default allocator.
-template <class _Tp, class _Tp1>
-struct _Alloc_traits<_Tp, allocator<_Tp1> >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
-  typedef allocator<_Tp> allocator_type;
-};
-//@}
-
-//@{
-/// Versions for the predefined "SGI" style allocators.
-template <class _Tp, int __inst>
-struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
-  typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
-};
-
-#ifndef __USE_MALLOC
-template <class _Tp, bool __threads, int __inst>
-struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> > 
-          _Alloc_type;
-  typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> > 
-          allocator_type;
-};
-#endif
+  /// The version for the default allocator.
+  template<typename _Tp, typename _Tp1>
+    struct _Alloc_traits<_Tp, allocator<_Tp1> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __alloc> _Alloc_type;
+      typedef allocator<_Tp> allocator_type;
+    };
+  //@}
 
-template <class _Tp, class _Alloc>
-struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
-  typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
-};
-//@}
-
-//@{
-/// Versions for the __allocator adaptor used with the predefined "SGI" style allocators.
-template <class _Tp, class _Tp1, int __inst>
-struct _Alloc_traits<_Tp, 
-                     __allocator<_Tp1, __malloc_alloc_template<__inst> > >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
-  typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
-};
-
-#ifndef __USE_MALLOC
-template <class _Tp, class _Tp1, bool __thr, int __inst>
-struct _Alloc_traits<_Tp, 
-                      __allocator<_Tp1, 
-                                  __default_alloc_template<__thr, __inst> > >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> > 
-          _Alloc_type;
-  typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> > 
-          allocator_type;
-};
-#endif
+  //@{
+  /// Versions for the predefined "SGI" style allocators.
+  template<typename _Tp, int __inst>
+    struct _Alloc_traits<_Tp, __malloc_alloc_template<__inst> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
+      typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
+    };
 
-template <class _Tp, class _Tp1, class _Alloc>
-struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
-{
-  static const bool _S_instanceless = true;
-  typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
-  typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
-};
-//@}
+  template<typename _Tp, bool __threads, int __inst>
+    struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __default_alloc_template<__threads, __inst> >
+      _Alloc_type;
+      typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
+      allocator_type;
+    };
+
+  template<typename _Tp, typename _Alloc>
+    struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
+      typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
+    };
+  //@}
+
+  //@{
+  /// Versions for the __allocator adaptor used with the predefined
+  /// "SGI" style allocators.
+  template<typename _Tp, typename _Tp1, int __inst>
+    struct _Alloc_traits<_Tp,
+                         __allocator<_Tp1, __malloc_alloc_template<__inst> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __malloc_alloc_template<__inst> > _Alloc_type;
+      typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
+    };
+
+  template<typename _Tp, typename _Tp1, bool __thr, int __inst>
+    struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __default_alloc_template<__thr,__inst> >
+      _Alloc_type;
+      typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
+      allocator_type;
+    };
+
+  template<typename _Tp, typename _Tp1, typename _Alloc>
+    struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
+    {
+      static const bool _S_instanceless = true;
+      typedef __simple_alloc<_Tp, __debug_alloc<_Alloc> > _Alloc_type;
+      typedef __allocator<_Tp, __debug_alloc<_Alloc> > allocator_type;
+    };
+  //@}
 
   // Inhibit implicit instantiations for required instantiations,
-  // which are defined via explicit instantiations elsewhere.  
+  // which are defined via explicit instantiations elsewhere.
   // NB: This syntax is a GNU extension.
   extern template class allocator<char>;
   extern template class allocator<wchar_t>;
-#ifdef __USE_MALLOC
-  extern template class __malloc_alloc_template<0>;
-#else
-  extern template class __default_alloc_template<true, 0>;
-#endif
+  extern template class __default_alloc_template<true,0>;
 } // namespace std
 
-#endif /* __GLIBCPP_INTERNAL_ALLOC_H */
-
-// Local Variables:
-// mode:C++
-// End:
+#endif
index d8879a7bccd82984378b4272e1dcc6d83b28354e..d80a718671847786b779475205ae5e7eb0571f04 100644 (file)
@@ -39,9 +39,5 @@ namespace std
   template class allocator<char>;
   template class allocator<wchar_t>;
 
-#ifdef __USE_MALLOC
-  template class __malloc_alloc_template<0>;
-#else
   template class __default_alloc_template<true, 0>;
-#endif
 } // namespace std
index 5d6cdd7160060683ca5e5736b2ba2255695a6544..8c40ab760f7fc051a2bb7707f0cf31a9f33c3e8b 100644 (file)
@@ -1,6 +1,6 @@
 // 2001-06-14  Benjamin Kosnik  <bkoz@redhat.com>
 
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -21,6 +21,7 @@
 // 20.4.1.1 allocator members
 
 #include <memory>
+#include <stdexcept>
 #include <cstdlib>
 #include <testsuite_hooks.h>
 
@@ -42,7 +43,7 @@ void operator delete(void *v) throw()
   return std::free(v);
 }
 
-int main(void)
+void test01()
 {
   bool test = true;
   std::allocator<gnu> obj;
@@ -55,6 +56,34 @@ int main(void)
 
   obj.deallocate(pobj, 256);
   VERIFY( check_delete );
+}
+
+// libstdc++/8230
+void test02()
+{
+  bool test = true;
+  try 
+    {
+      std::allocator<int> alloc;
+      const std::allocator<int>::size_type n = alloc.max_size();
+      int* p = alloc.allocate(n + 1);
+      p[n] = 2002;
+    } 
+  catch(const std::bad_alloc& e) 
+    {
+      // Allowed.
+      test = true;
+    }
+  catch(...) 
+    {
+      test = false;
+    }
+  VERIFY( test );
+}
 
+int main()
+{
+  test01();
+  test02();
   return 0;
 }
index 6ffaa06f9e44343118d70c61abb02976a695a1cb..8473909103b110d15418564240578ffb9d5b73a1 100644 (file)
@@ -209,7 +209,7 @@ void test01()
   sz02 = str011.length();
   VERIFY( sz02 > sz01 );
     
-  // trickster allocator (__USE_MALLOC, luke) issues involved with these:
+  // trickster allocator issues involved with these:
   std::string str3 = "8-chars_8-chars_";
   const char* p3 = str3.c_str();
   std::string str4 = str3 + "7-chars";
index e73b15a3246876741053bd57cb616f6f761aff07..8e9b6a8b1ab205e146331c90d5fa8f490b12e919 100644 (file)
@@ -99,9 +99,30 @@ void test02()
   }
 }
 
+void test03()
+{
+  bool test = true;
+  std::vector<int> v;
+  try
+    {
+      v.resize(v.max_size());  
+      v[v.max_size() - 1] = 2002;
+    }
+  catch (const std::bad_alloc& error)
+    {
+      test = true;
+    }
+  catch (...)
+    {
+      test = false;
+    }
+  VERIFY( test );
+}
+
 int main()
 {
   test01();
   test02();
+  test03();
   return 0;
 }
index c093cd507a6aa1f12cd50a1d8bff654c1c74e4fd..e956090e7098a77ee37608f2054ee736c85e004b 100644 (file)
@@ -134,7 +134,7 @@ const char*
 demangle(const std::string& mangled)
 {
   const char* name;
-  if (mangled[0] != '_' && mangled[1] != 'Z')
+  if (mangled[0] != '_' || mangled[1] != 'Z')
     {
       // This is not a mangled symbol, thus has "C" linkage.
       name = mangled.c_str();
@@ -365,6 +365,8 @@ main(int argc, char** argv)
     {
       vector<string> compatible_versions;
       compatible_versions.push_back("GLIBCPP_3.2.1");
+      compatible_versions.push_back("GLIBCPP_3.2.2");
+      compatible_versions.push_back("CXXABI_1.2.1");
 
       symbol_info test = test_symbols[added_names[i]];
       vector<string>::iterator end = compatible_versions.end();
index b3068e0b2ddf2880f8594336e3498692c65bd5f8..99226255d5b5982e2a0c522184db37a5f402d7c9 100644 (file)
@@ -1,6 +1,6 @@
 // 2001-11-25  Phil Edwards  <pme@gcc.gnu.org>
 //
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002 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
@@ -20,7 +20,6 @@
 
 // 20.4.1.1 allocator members
 
-#undef __USE_MALLOC
 #include <memory>
 #include <cstdlib>
 #include <testsuite_hooks.h>
@@ -75,7 +74,8 @@ void test()
 
   std::__allocator<big, arbitrary_SGIstyle_allocator>   a;
   big *p = a.allocate(10);
-  if (uses_global_new_and_delete)  VERIFY (requested >= (10*15*sizeof(long)));
+  if (uses_global_new_and_delete)  
+    VERIFY (requested >= (10 * 15 * sizeof(long)));
   // Touch the far end of supposedly-allocated memory to check that we got
   // all of it.  Why "3"?  Because it's my favorite integer between e and pi.
   p[9].f[14] = 3;