stdcxx-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From se...@apache.org
Subject svn commit: r372017 - /incubator/stdcxx/trunk/tests/self/0.new.cpp
Date Tue, 24 Jan 2006 21:03:41 GMT
Author: sebor
Date: Tue Jan 24 13:03:38 2006
New Revision: 372017

URL: http://svn.apache.org/viewcvs?rev=372017&view=rev
Log:
2006-01-24  Liviu Nicoara <nicoara@roguewave.com>
	    Martin Sebor  <sebor@roguewave.com>

	STDCXX-4
	* 0.new.cpp: New test exercising the testsuite's replacement operators
	new and delete.

Added:
    incubator/stdcxx/trunk/tests/self/0.new.cpp   (with props)

Added: incubator/stdcxx/trunk/tests/self/0.new.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/self/0.new.cpp?rev=372017&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/self/0.new.cpp (added)
+++ incubator/stdcxx/trunk/tests/self/0.new.cpp Tue Jan 24 13:03:38 2006
@@ -0,0 +1,505 @@
+/***************************************************************************
+ *
+ * 0.new.cpp - test exercising replacement operator new and delete
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Copyright (c) 1994-2005 Quovadx,  Inc., acting through its  Rogue Wave
+ * Software division. Licensed under the Apache License, Version 2.0 (the
+ * "License");  you may  not use this file except  in compliance with the
+ * License.    You    may   obtain   a   copy   of    the   License    at
+ * http://www.apache.org/licenses/LICENSE-2.0.    Unless   required    by
+ * applicable law  or agreed to  in writing,  software  distributed under
+ * the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR
+ * CONDITIONS OF  ANY KIND, either  express or implied.  See  the License
+ * for the specific language governing permissions  and limitations under
+ * the License.
+ * 
+ **************************************************************************/
+
+#include <new>        // for bad_alloc
+
+#include <cstddef>    // for size_t
+
+#include <setjmp.h>   // for longjmp(), setjmp()
+#include <signal.h>   // for SIGABRT, signal()
+
+#include <rw_new.h>
+#include <driver.h>
+
+/**************************************************************************/
+
+// program exit status
+int exit_status /* = 0 */;
+
+extern "C" {
+
+volatile int line;   // currently executed line
+volatile int fail;   // non-zero when line failed
+
+jmp_buf env;
+
+static void
+handle_ABRT (int)
+{
+    fail = 0;
+
+    longjmp (env, 1);
+}
+
+}
+
+#define FAIL(code)                                              \
+    fail = line = __LINE__;                                     \
+    signal (SIGABRT, handle_ABRT);                              \
+    if (0 == setjmp (env)) {                                    \
+        code;                                                   \
+        exit_status = 1;                                        \
+        rw_assert (0, __FILE__, line, "expected assertion");    \
+    }                                                           \
+    else                                                        \
+        (void)0
+
+#define PASS(code)                                              \
+    fail = -1; line = __LINE__;                                 \
+    signal (SIGABRT, handle_ABRT);                              \
+    if (0 == setjmp (env)) {                                    \
+        code;                                                   \
+    }                                                           \
+    else if (fail != line) {                                    \
+        exit_status = 1;                                        \
+        rw_assert (0, __FILE__, line, "unexpected assertion");  \
+    } (void)0
+
+/**************************************************************************/
+
+void test_new_delete ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising successful allocation and deallocation");
+
+    {
+        void *p = 0;
+        PASS (p = operator new (0));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new(0) != 0");
+        operator delete (p);
+    }
+
+    {
+        void *p = 0;
+        PASS (p = operator new (1));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new(1) != 0");
+        operator delete (p);
+    }
+
+    {
+        void *p = 0;
+        PASS (p = operator new (2));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new(2) != 0");
+        operator delete (p);
+    }
+
+    {
+        void *p = 0;
+        PASS (p = operator new (1024));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new(1024) != 0");
+        operator delete (p);
+    }
+}
+
+/**************************************************************************/
+
+#define CATCH(code)                                     \
+    try { code; fail = 1; }                             \
+    catch (_RWSTD_BAD_ALLOC) { fail = 0; }              \
+    catch (...) { fail = 2; }                           \
+    rw_assert (!fail, __FILE__, __LINE__,               \
+               "%s", 1 == fail ? "failed to throw" :    \
+               "threw an unknown exception")
+
+#define NOTHROW(code)                           \
+    try { fail = 0; code; }                     \
+    catch (...) { fail = 1; }                   \
+    rw_assert (!fail, __FILE__, __LINE__,       \
+               "unexpected exception")
+
+void test_bad_alloc ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability of ordinary "
+             "operator new to throw std::bad_alloc");
+
+    rwt_free_store* const pst = rwt_get_free_store (0);
+
+    *pst->throw_at_blocks_ [0] = pst->blocks_ [0];
+
+    CATCH (operator new (0));
+    CATCH (operator new (1));
+    CATCH (operator new (2));
+    CATCH (operator new (1024));
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new[](0));
+        operator delete[](p);
+    }
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new[](1));
+        operator delete[](p);
+    }
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new[](2));
+        operator delete[](p);
+    }
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new[](1024));
+        operator delete[](p);
+    }
+
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability of the array form "
+             "of operator new to throw std::bad_alloc");
+
+    *pst->throw_at_blocks_ [0] = std::size_t (-1);
+    *pst->throw_at_blocks_ [1] = pst->blocks_ [1];
+
+    CATCH (operator new[](0));
+    CATCH (operator new[](1));
+    CATCH (operator new[](2));
+    CATCH (operator new[](1024));
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new (0));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new[](0) != 0");
+        operator delete (p);
+    }
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new (1));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new[](1) != 0");
+        operator delete (p);
+    }
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new (32));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new[](32) != 0");
+        operator delete (p);
+    }
+
+    {
+        void *p = 0;
+        NOTHROW (p = operator new (4096));
+        rw_assert (p != 0, __FILE__, __LINE__, "operator new[](4096) != 0");
+        operator delete (p);
+    }
+
+    *pst->throw_at_blocks_ [1] = std::size_t (-1);
+}
+
+/**************************************************************************/
+
+void test_mismatch ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability to detect "
+             "allocation/deallocation mismatches");
+    
+    {
+        // detect allocations by operator new() deallocated
+        // using (the array form of) operator delete[]
+        void *p = 0;
+        PASS (p = operator new (0));
+        FAIL (operator delete[](p));
+        PASS (operator delete (p));
+    }
+
+    {
+        void *p = 0;
+        PASS (p = operator new (1));
+        FAIL (operator delete[](p));
+        PASS (operator delete (p));
+    }
+
+    {
+        void *p = 0;
+        PASS (p = operator new[](33));
+        FAIL (operator delete (p));
+        PASS (operator delete[] (p));
+    }
+}
+
+/**************************************************************************/
+
+void test_bad_delete ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability to detect "
+             "deletion of unallocated storage");
+
+    {
+        char *p = 0;
+        PASS (p = new char);
+
+        FAIL (delete (p - 1));
+        FAIL (delete (p + 1));
+
+        PASS (delete (p));
+    }
+
+    {
+        char *p = 0;
+        PASS (p = new char [4]);
+
+        FAIL (delete (p - 1));
+        FAIL (delete (p + 1));
+        FAIL (delete (p + 2));
+        FAIL (delete (p + 3));
+        FAIL (delete (p + 4));
+
+        FAIL (delete[] (p - 1));
+        FAIL (delete[] (p + 1));
+        FAIL (delete[] (p + 2));
+        FAIL (delete[] (p + 3));
+        FAIL (delete[] (p + 4));
+
+        PASS (delete[] p);
+    }
+}
+
+/**************************************************************************/
+
+void test_double_delete ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability to detect double deletion");
+
+    {
+        char *p = 0;
+        PASS (p = new char);
+
+        PASS (delete (p));
+        FAIL (delete (p));
+    }
+
+    {
+        char *p = 0;
+        PASS (p = new char [32]);
+
+        PASS (delete[] p);
+        FAIL (delete[] p);
+        FAIL (delete p);
+    }
+}
+
+/**************************************************************************/
+
+void test_corruption ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability to detect memory corruption");
+
+    // corrupt (and restore) memory past the end of the allocated block
+    for (std::size_t i = 1; i != 8; ++i) {
+        char *p = 0;
+        PASS (p = new char);
+
+        // save the value of the byte past the end of the block
+        // and temporarily overwrite it with another value
+        const char save = p [i];
+        p [i] = ~p [i];
+
+        // expect operator delete to diagnose the corruption
+        // and call abort() without actually freeing the block
+        FAIL (delete p);
+
+        // restore the corrupted byte to its original value
+        p [i] = save;
+
+        // expect operator delete not to complain
+        PASS (delete p);
+    }
+}
+
+/**************************************************************************/
+
+#define LEAK(code, bytes, blks)                                         \
+    do {                                                                \
+        /* establish a checkpoint for memory leaks */                   \
+        rwt_check_leaks (0, 0);                                         \
+                                                                        \
+        code;                                                           \
+                                                                        \
+        /* find memory leaks since the last checkpoint */               \
+        std::size_t nbytes;                                             \
+        const std::size_t nblocks = rwt_check_leaks (&nbytes, 0);       \
+                                                                        \
+        rw_assert (blks == nblocks && bytes == nbytes,                  \
+                   __FILE__, __LINE__,                                  \
+                   "failed to detect a leak of %d bytes in "            \
+                   "%d blocks: got %zu bytes in %zu blocks",            \
+                   bytes, blks, nbytes, nblocks);                       \
+    } while (0)
+
+
+void test_leaks ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "exercising the ability to detect memory leaks");
+
+    {
+        void *p = 0;
+        LEAK (p = operator new (0), 0, 1);
+        PASS (operator delete (p));
+    }
+
+    {
+        void *p = 0;
+        LEAK (p = operator new (1), 1, 1);
+        PASS (operator delete (p));
+    }
+
+    {
+        void *p = 0;
+        LEAK (p = operator new (1234), 1234, 1);
+        PASS (operator delete (p));
+    }
+
+    {
+        void *p0 = 0;
+        void *p1 = 0;
+        LEAK (p0 = operator new (32);
+              p1 = operator new (64), 96, 2);
+        PASS (operator delete (p0));
+        PASS (operator delete (p1));
+    }
+
+    {
+        void *p = 0;
+        LEAK (p = operator new[] (12345), 12345, 1);
+        PASS (operator delete[] (p));
+    }
+}
+
+/**************************************************************************/
+
+void test_stress ()
+{
+    rw_info (0, __FILE__, __LINE__, 
+             "stress-testing replacement operators new and delete");
+
+    rwt_free_store* const pst = rwt_get_free_store (0);
+
+    std::size_t nblocks = pst->blocks_ [0] + pst->blocks_ [1];
+    std::size_t nbytes  = pst->bytes_ [0] + pst->bytes_ [1];
+
+    void* ptrs [1000];
+
+    const std::size_t N = sizeof ptrs / sizeof *ptrs;
+
+    for (std::size_t i = 0; i != N; ++i) {
+        if (i % 2) {
+            PASS (ptrs [i] = operator new[](i));
+        }
+        else {
+            PASS (ptrs [i] = operator new (i));
+        }
+    }
+
+    for (std::size_t i = 0; i < N; ++i) {
+
+        const std::size_t j = (i * (i + 17)) % N;
+
+        if (j % 2) {
+            PASS (operator delete[](ptrs [j]));
+        }
+        else {
+            PASS (operator delete (ptrs [j]));
+        }
+
+        ptrs [j] = 0;
+    }
+
+    for (std::size_t i = 0; i < N; ++i) {
+        if (i % 2) {
+            PASS (operator delete[](ptrs [i]));
+        }
+        else {
+            PASS (operator delete (ptrs [i]));
+        }
+    }
+
+    nblocks = pst->blocks_ [0] + pst->blocks_ [1] - nblocks;
+    nbytes  = pst->bytes_ [0] + pst->bytes_ [1] - nbytes;
+
+    rw_assert (0 == nblocks && 0 == nbytes, __FILE__, __LINE__,
+               "false leaks detected: %zu bytes in %zu blocks", 
+               nbytes, nblocks);
+}
+
+/**************************************************************************/
+
+static int rw_opt_no_new_delete;      // for --no-new-delete
+static int rw_opt_no_bad_alloc;       // for --no-bad_alloc
+static int rw_opt_no_mismatch;        // for --no-mismatch
+static int rw_opt_no_bad_delete;      // for --no-bad-delete
+static int rw_opt_no_double_delete;   // for --no-double-delete
+static int rw_opt_no_corruption;      // for --no-corruption
+static int rw_opt_no_leaks;           // for --no-leaks
+static int rw_opt_no_stress;          // for --no-stress
+
+int run_test (int, char**)
+{
+#define TEST(name)                                              \
+    if (rw_opt_no_ ## name)                                     \
+        rw_note (0, 0, __LINE__, "%s test disabled", #name);    \
+else                                                            \
+        test_ ## name ()
+
+
+    TEST (bad_alloc);
+    TEST (mismatch);
+    TEST (double_delete);
+    TEST (bad_delete);
+    TEST (corruption);
+    TEST (leaks);
+    TEST (stress);
+
+    return 0;
+}
+
+/**************************************************************************/
+
+int main (int argc, char** argv)
+{
+    return rw_test (argc, argv, __FILE__,
+                    0 /* no clause */,
+                    0 /* no comment */,
+                    run_test,
+                    "|-no-new-delete# "
+                    "|-no-bad_alloc# "
+                    "|-no-mismatch# "
+                    "|-no-bad-delete# "
+                    "|-no-double-delete# "
+                    "|-no-corruption# "
+                    "|-no-leaks# "
+                    "|-no-stress-test#",
+                    &rw_opt_no_new_delete,
+                    &rw_opt_no_bad_alloc,
+                    &rw_opt_no_mismatch,
+                    &rw_opt_no_bad_delete,
+                    &rw_opt_no_double_delete,
+                    &rw_opt_no_corruption,
+                    &rw_opt_no_leaks,
+                    &rw_opt_no_stress);
+}

Propchange: incubator/stdcxx/trunk/tests/self/0.new.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/stdcxx/trunk/tests/self/0.new.cpp
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message