Author: vitek
Date: Mon Apr 7 18:05:14 2008
New Revision: 645750
URL: http://svn.apache.org/viewvc?rev=645750&view=rev
Log:
2008-04-07 Travis Vitek <[EMAIL PROTECTED]>
* tests/support/18.support.dynamic.cpp: New test exercising
functions and types for dynamic storage management.
* tests/support/18.support.rtti.cpp: New test exercising
types for dynamic type information support.
* tests/diagnostics/19.std.exceptions.cpp: New test exercising
standard exception types.
Added:
stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp (with props)
stdcxx/trunk/tests/support/18.support.dynamic.cpp (with props)
stdcxx/trunk/tests/support/18.support.rtti.cpp (with props)
Added: stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp?rev=645750&view=auto
==============================================================================
--- stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp (added)
+++ stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp Mon Apr 7 18:05:14
2008
@@ -0,0 +1,458 @@
+/***************************************************************************
+ *
+ * 19.std.exceptions.cpp - test exercising [lib.std.exceptions]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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.
+ *
+ * Copyright 2001-2008 Rogue Wave Software.
+ *
+ **************************************************************************/
+
+#include <stdexcept>
+
+/**************************************************************************/
+
+
+template <class Exception>
+int test_ex_spec (Exception*, const char *str)
+{
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ try {
+ // also tests that exception objects can be constructed
+ // from a const char* argument w/o <string> having been
+ // explicitly #included first
+ Exception e (str);
+ (void)&e;
+ }
+ catch (...) {
+ return 1;
+ }
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS);
+
+ _RWSTD_UNUSED (str);
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ return 0;
+}
+
+/**************************************************************************/
+
+#include <string>
+
+/**************************************************************************/
+
+
+// helpers to verify that each exception's ctor is explicit
+// not defined since they must not be referenced if test is successful
+void is_explicit (const std::logic_error&);
+void is_explicit (const std::domain_error&);
+void is_explicit (const std::invalid_argument&);
+void is_explicit (const std::length_error&);
+void is_explicit (const std::out_of_range&);
+void is_explicit (const std::runtime_error&);
+void is_explicit (const std::range_error&);
+void is_explicit (const std::overflow_error&);
+void is_explicit (const std::underflow_error&);
+
+struct bogus_exception
+{
+ // also verifies that std::string is declared
+ bogus_exception (const std::string&) { }
+ bogus_exception (const char*) { }
+};
+
+// calls to the overoaded is_explicit (std::string ()) must resolve
+// to this function since there must be no implicit conversion from
+// std::string to any of the exception classes
+void is_explicit (const bogus_exception&) { }
+
+// exercise the ability to construct exception objects w/o
+// explicitly #including <string> first; std::string must still
+// be declared (but not necessarily defined)
+
+#if !defined (_RWSTD_NO_NAMESPACE) && !defined (_RWSTD_NO_HONOR_STD)
+ // declare a global function with the same name as exception
+# define TEST_NAMESPACE_DEF(T) void T ()
+#else
+# define TEST_NAMESPACE_DEF(ignore) (void)0
+#endif // !_RWSTD_NO_NAMESPACE && !_RWSTD_NO_HONOR_STD
+
+
+#ifndef _RWSTD_NO_PTR_EXCEPTION_SPEC
+# define _PTR_THROWS(spec) _THROWS (spec)
+#else // if defined (_RWSTD_NO_PTR_EXCEPTION_SPEC)
+ // throw specs on pointers to functions not implemented...
+# define _PTR_THROWS(ignore)
+#endif // _RWSTD_NO_PTR_EXCEPTION_SPEC
+
+
+// verify that each name is declared in namespace std
+// w/o polluting the global namespace
+#define TEST_DEF(T) \
+ typedef std::T T ## _type; \
+ TEST_NAMESPACE_DEF (T); \
+ /* construct an object */ \
+ std::T obj_ ## T ("std::" _RWSTD_STR (T)); \
+ /* assign the address of object to std::exception* */ \
+ e = &obj_ ## T; \
+ /* verify that assignment can't throw */ \
+ std::T& (std::T::*p_assign_ ## T)(const std::T&) \
+ _PTR_THROWS(()) = &std::T::operator=; \
+ _RWSTD_UNUSED (p_assign_ ## T); \
+ /* verify that what() can't throw */ \
+ const char* (std::T::*p_what_ ## T)() const \
+ _PTR_THROWS(()) = &std::T::what; \
+ _RWSTD_UNUSED (p_what_ ## T); \
+ /* verify ctor postcondition */ \
+ result = result << 1 | cmp (obj_ ## T.what (), \
+ "std::" _RWSTD_STR (T))
+
+
+int cmp (const char *s1, const char *s2)
+{
+ for (; *s1 && *s1 == *s2; ++s1, ++s2);
+ return *s2 - *s1;
+}
+
+
+// returns 0 on success; on failure returns a bitmap with one bit set
+// for every exception that failed its ctor postcondition
+static int test_exception_defs ()
+{
+ int result = 0;
+
+ // used below to verify public inheritance from std::exception
+ std::exception *e = 0;
+
+ TEST_DEF (logic_error);
+ TEST_DEF (domain_error);
+ TEST_DEF (invalid_argument);
+ TEST_DEF (length_error);
+ TEST_DEF (out_of_range);
+ TEST_DEF (runtime_error);
+ TEST_DEF (range_error);
+ TEST_DEF (overflow_error);
+ TEST_DEF (underflow_error);
+
+ _RWSTD_UNUSED (e);
+
+#ifndef _RWSTD_NO_EXPLICIT
+
+ // verify that each exceptions converting ctor is explicit
+ // use a pointer since std::string need not be a complete class
+ const char s[40] = "";
+ const std::string *ps = _RWSTD_REINTERPRET_CAST (const std::string*, s);
+ is_explicit (*ps);
+
+ // verify that each exceptions converting ctor from const char*
+ // (if one exists) is also explicit
+ is_explicit (s);
+
+#endif // _RWSTD_NO_EXPLICIT
+
+ return result;
+}
+
+#undef _PTR_THROWS
+
+/**************************************************************************/
+
+#include <rw_new.h>
+#include <driver.h>
+#include <cstddef>
+
+/**************************************************************************/
+
+
+template <class Exception>
+int test_throw (Exception*, const char *str)
+{
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ //////////////////////////////////////////////////////////////////
+
+ try {
+ throw Exception (str);
+ }
+ catch (const Exception &e) {
+ // caught by const reference
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught by const reference; %s::what() == %#s",
+ str, str);
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "threw %s, caught an unknown exception", str);
+ }
+
+ //////////////////////////////////////////////////////////////////
+
+ try {
+ throw Exception (str);
+ }
+ catch (Exception e) {
+ // caught by value
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught by value; %s::what() == %#s",
+ str, str);
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "threw %s, caught an unknown exception", str);
+ }
+
+ //////////////////////////////////////////////////////////////////
+
+ const Exception ex (str);
+
+ try {
+ throw ex;
+ }
+ catch (Exception e) {
+ // caught copy by value
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught copy by value; %s::what() == %#s",
+ str, str);
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "threw %s, caught an unknown exception", str);
+ }
+
+ //////////////////////////////////////////////////////////////////
+
+ try {
+ throw ex;
+ }
+ catch (std::exception &e) {
+ // caught by non-const reference to a base class
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught by non-const reference to base; %s::what() == %#s",
+ str, str);
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "threw %s, caught an unknown exception", str);
+ }
+
+ //////////////////////////////////////////////////////////////////
+
+ try {
+ try {
+ throw Exception (str);
+ }
+ catch (...) {
+ // rethrown
+ throw;
+ }
+ }
+ catch (Exception e) {
+ // rethrown object caught by value
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught rethrown by value; %s::what() == %#s", str, str);
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "threw %s, caught an unknown exception", str);
+ }
+
+ //////////////////////////////////////////////////////////////////
+
+ try {
+ try {
+ throw Exception (str);
+ }
+ catch (Exception e) {
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught by value; %s::what() == %#s",
+ str, str);
+
+ // rethrown by value
+ throw e;
+ }
+ }
+ catch (Exception e) {
+ // rethrown object caught by value
+ rw_assert (e.what () && !cmp (e.what (), str),
+ 0, __LINE__,
+ "caught rethrown copy by value; %s::what() == %#s",
+ str, str);
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "threw %s, caught an unknown exception", str);
+ }
+
+#else // if defined (_RWSTD_NO_EXCEPTIONS);
+
+ _RWSTD_UNUSED (t);
+ _RWSTD_UNUSED (str);
+
+#endif // _RWSTD_NO_EXCEPTIONS
+
+ return 0;
+}
+
+/**************************************************************************/
+
+
+static int
+run_test (int, char* [])
+{
+ // verify that exception's (and its derivatives') ctor is explicit
+ is_explicit (std::string ());
+
+ const char* const names[] = {
+ "logic_error", "domain_error", "invalid_argument", "length_error",
+ "out_of_range", "runtime_error", "range_error", "overflow_error",
+ "underflow_error"
+ };
+
+ // if set, each bit corresponds to a failed exception assertion
+ const int failures = test_exception_defs ();
+
+ for (unsigned i = 0; i != sizeof names / sizeof *names; ++i) {
+ rw_assert (!(failures & (1 << i)), 0, __LINE__,
+ "std::%s::%s (const std::string&) postcondition",
+ names [i]);
+ }
+
+
+ // have replacement operator new throw an exception
+ rwt_free_store* const pst = rwt_get_free_store (0);
+ *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + 1;
+
+ // create a very long string to guarantee that exception ctors
+ // try to dynamically allocate storage even if it otherwise
+ // use some clever scheme to avoid doing so
+ char long_str [0x10000];
+ for (unsigned i = 0; i != sizeof long_str - 1; ++i)
+ long_str [i] = '*';
+
+ long_str [sizeof long_str - 1] = '\0';
+
+ int new_throws = 0;
+
+ _TRY {
+ // see if replacement operator new throws an exception
+ // when called directly from the program
+ void *p = ::operator new (sizeof long_str);
+ ::operator delete (p);
+ new_throws = 0;
+
+ rw_assert (false, 0, __LINE__,
+ "replacement ::operator new(std::size_t = %u) failed "
+ "to throw when called directly from a program",
+ sizeof long_str);
+ }
+ _CATCH (...) {
+ new_throws = 1;
+ }
+
+ *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + 1;
+
+ _TRY {
+ // see if replacement operator new throws an exception
+ // when called indirectly, i.e., from the library binary
+ void* const p = _RW::__rw_allocate (sizeof long_str, 0);
+ _RW::__rw_deallocate (p, 0);
+ new_throws = 0;
+
+#ifdef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ // MSVC and VAC++ don't reliably replace operators
+ // new and delete across shared librray boundaries
+
+ rw_warn (false, 0, __LINE__,
+ "replacement ::operator new(std::size_t = %u) failed "
+ "to throw when called from the library: this is an "
+ "expected failure on this platform",
+ sizeof long_str);
+
+#else // if !defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
+
+ rw_assert (false, 0, __LINE__,
+ "replacement ::operator new(std::size_t = %u) "
+ "unexpectdly failed to throw when called from "
+ "the library",
+ sizeof long_str);
+
+#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ }
+ _CATCH (...) {
+ new_throws = 1;
+ }
+
+// exercise exception specification on class ctors
+// and the ability to throw and catch exception objects
+#define TEST_EX_SPEC(T) do { \
+ /* do not induce an exception from replacement operator new */ \
+ *pst->throw_at_calls_ [0] = std::size_t (-1); \
+ *pst->throw_at_calls_ [1] = std::size_t (-1); \
+ /* verify that exception objects can be thrown, caught, and rethrown */\
+ test_throw ((std:: T*)0, "std::" #T); \
+ /* induce an exception from replacement operator new */ \
+ *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + 1; \
+ *pst->throw_at_calls_ [1] = pst->new_calls_ [1] + 1; \
+ /* verify that each exception ctor propagates the exception thrown */ \
+ /* from operator new(); failure wil cause a call to terminate() */ \
+ /* tests are expected to silently fail if (0 == new_throws) holds */ \
+ const int threw = test_ex_spec ((std::T*)0, long_str); \
+ rw_assert (threw == new_throws, 0, __LINE__, \
+ "attempthing to construct a std::" #T " %s an exception", \
+ new_throws ? "failed to rethrow" : "unexpectedly threw"); \
+ } while (0)
+
+ TEST_EX_SPEC (logic_error);
+ TEST_EX_SPEC (domain_error);
+ TEST_EX_SPEC (invalid_argument);
+ TEST_EX_SPEC (length_error);
+ TEST_EX_SPEC (out_of_range);
+ TEST_EX_SPEC (runtime_error);
+ TEST_EX_SPEC (range_error);
+ TEST_EX_SPEC (overflow_error);
+ TEST_EX_SPEC (underflow_error);
+
+ return 0;
+}
+
+/**************************************************************************/
+
+
+int main (int argc, char* argv [])
+{
+ return rw_test (argc, argv, __FILE__,
+ "lib.std.exceptions",
+ 0 /* no comment */,
+ run_test,
+ "",
+ (void*)0);
+}
Propchange: stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: stdcxx/trunk/tests/diagnostics/19.std.exceptions.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Added: stdcxx/trunk/tests/support/18.support.dynamic.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/support/18.support.dynamic.cpp?rev=645750&view=auto
==============================================================================
--- stdcxx/trunk/tests/support/18.support.dynamic.cpp (added)
+++ stdcxx/trunk/tests/support/18.support.dynamic.cpp Mon Apr 7 18:05:14 2008
@@ -0,0 +1,478 @@
+/***************************************************************************
+ *
+ * 18.support.dynamic.cpp - test exercising [lib.support.dynamic]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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.
+ *
+ * Copyright 2001-2008 Rogue Wave Software.
+ *
+ **************************************************************************/
+
+#include <new>
+#include <memory>
+#include <driver.h>
+
+#include <rw/_defs.h>
+#include <rw/_error.h>
+
+#include <cstdlib> // for malloc() and free()
+#include <cstring> // for strlen()
+
+
+#ifdef _MSC_VER
+ // verify that <new> et al can coexist with MSVC's <new.h>
+# include <new.h>
+#endif
+
+/**************************************************************************/
+
+// detects recursive implementation of operator new (size_t, nothrow_t)
+static int recursive_new_nothrow = 0;
+static int recursive_delete_nothrow = 0;
+
+// MemoryAllocator is used to replace the global new and delete
+// in order to test conformance of of the other operators that
+// might be defined in <new>
+
+struct MemoryAllocator
+{
+ MemoryAllocator () {
+ init ();
+ }
+
+ void* operatorNew (std::size_t n) _THROWS ((std::bad_alloc)) {
+ _allocPtr = 0;
+ _newCalled = true;
+ _bytesRequested = n;
+ if (_failAlloc) {
+ _failAlloc = false;
+ _THROW (std::bad_alloc ());
+ }
+#if !defined (_RWSTD_NO_EXT_OPERATOR_NEW) && \
+ defined (_RWSTD_NO_OPERATOR_NEW_NOTHROW)
+
+ // test our implementation of
+ // ::operator new(size_t, const std::nothrow)
+ // this operator must not be implemented in terms
+ // of ::operator new(size_t) to prevent recursion
+
+ if (recursive_new_nothrow++)
+ _allocPtr = std::malloc (_bytesRequested);
+ else
+ _allocPtr = ::operator new (_bytesRequested, std::nothrow);
+
+ --recursive_new_nothrow;
+
+#else
+ _allocPtr = std::malloc (_bytesRequested);
+#endif
+ return _allocPtr;
+ }
+
+ void operatorDelete (void* ptr) _THROWS (()) {
+ _deallocPtr = ptr;
+#if !defined (_RWSTD_NO_EXT_OPERATOR_NEW) && \
+ defined (_RWSTD_NO_OPERATOR_NEW_NOTHROW)
+ // memory allocated by our nothrow operator new()
+ if (recursive_delete_nothrow++ || recursive_new_nothrow)
+ std::free (ptr);
+ else
+ ::operator delete (ptr, std::nothrow);
+
+ --recursive_delete_nothrow;
+#else
+ std::free (ptr);
+#endif
+ _deleteCalled = true;
+ }
+
+ void init () {
+ _newCalled = _deleteCalled = _failAlloc = false;
+ _bytesRequested = 0;
+ _deallocPtr = _allocPtr = 0;
+ }
+
+ bool newCalled () {
+ bool tmp = _newCalled;
+ _newCalled = 0;
+ return tmp;
+ }
+
+ bool deleteCalled () {
+ bool tmp = _deleteCalled;
+ _deleteCalled = 0;
+ return tmp;
+ }
+
+ std::size_t _bytesRequested;
+ bool _newCalled;
+ bool _deleteCalled;
+ bool _failAlloc;
+ void* _allocPtr;
+ void* _deallocPtr;
+};
+
+
+// static instance of memory allocator
+static MemoryAllocator alloc;
+
+/**************************************************************************/
+
+
+// replace the global operators with MemoryAllocator versions
+void* operator new (std::size_t size) _THROWS ((std::bad_alloc))
+{
+ return alloc.operatorNew (size);
+}
+
+void operator delete (void* p) _THROWS (())
+{
+ alloc.operatorDelete (p);
+}
+
+/**************************************************************************/
+
+
+#define TEST_OP_THROWS(expr,cond,tag) \
+ _TRY { \
+ alloc._failAlloc = true; \
+ expr; \
+ rw_assert (cond, 0, __LINE__, tag); \
+ } \
+ _CATCH (std::bad_alloc) { \
+ RW_ASSERT (!cond, 0, __LINE__, tag); \
+ } \
+ _CATCH (...) { \
+ rw_assert (!cond, 0, __LINE__, tag); \
+ } \
+ (void)0
+
+/**************************************************************************/
+
+
+// provide a handler for unexpected exceptions so that at least the
+// test will log the event rather than just aborting
+void my_unexpected_handler ()
+{
+ rw_assert (false, 0, __LINE__, "caught an unexpected exception\n");
+}
+
+// used in exists_set_new_handler below
+void my_new_handler ()
+{
+}
+
+// grab default throw procedure
+void (*default_throw_proc)(int, char*) = _RW::__rw_throw_proc;
+
+bool my_throw_proc_called = false;
+
+// my_throw_proc just sets a global flag to indicate
+// that it was called, and then dispatches the call
+// to the default throw procedure
+static void my_throw_proc (int id, char* what)
+{
+ my_throw_proc_called = true;
+ default_throw_proc (id, what);
+}
+
+/**************************************************************************/
+
+
+static
+int run_test (int, char* [])
+{
+ std::set_unexpected (&my_unexpected_handler);
+
+ if (1) {
+ // exists_std_nothrow
+ const std::nothrow_t* p = &std::nothrow;
+ rw_assert (p != 0, 0, __LINE__, "std::nothrow defined");
+ }
+
+ if (1) {
+ // exists_bad_alloc
+ std::bad_alloc ba1; // default ctor
+ std::bad_alloc ba2 = ba1; // copy ctor
+
+ std::exception* e = &ba1; // derived from exception
+ (void) &e;
+ ba1 = ba2; // assignment operator
+
+ // verify that a member function is accessible and has the
+ // appropriate signature, including return type and exception
+ // specification
+
+ std::bad_alloc& (std::bad_alloc::*p_op_assign)
+ (const std::bad_alloc&) _PTR_THROWS (())
+ = &std::bad_alloc::operator=;
+ _RWSTD_UNUSED (p_op_assign);
+
+ const char*
+ (std::bad_alloc::*p_what_fn)() const _PTR_THROWS (())
+ = &std::bad_alloc::what;
+ _RWSTD_UNUSED (p_what_fn);
+
+ const char* s = ba1.what ();
+ rw_assert (s && 0 != std::strlen (s), 0, __LINE__,
+ "std::bad_alloc::what() returned bad string");
+ }
+
+ if (1) {
+ // set_new_handler
+ typedef void (*new_handler_t) ();
+
+ new_handler_t (*f) (new_handler_t) _PTR_THROWS (());
+ f = &std::set_new_handler;
+
+ rw_assert (f != 0, 0, __LINE__,
+ "std::set_new_handler() defined");
+
+ new_handler_t original_handler
+ = std::set_new_handler (my_new_handler);
+
+#if !defined (__EDG__) || __EDG_VERSION__ > 245 || defined (__DECCXX)
+
+ // EDG eccp 2.45 standalone demo is known to fail
+ rw_assert (original_handler == 0, 0, __LINE__,
+ "std::set_new_handler() unexpectedly returned "
+ "installed handler");
+
+#define _RWSTD_NO_EXT_OPERATOR_NEW
+
+#endif // !__EDG__ || __EDG_VERSION__ > 245 || __DECCXX
+
+ new_handler_t replacement_handler
+ = std::set_new_handler (original_handler);
+ rw_assert (my_new_handler == replacement_handler, 0, __LINE__,
+ "std::set_new_handler() failed to return previously "
+ "installed handler");
+ }
+
+ // test all operators that we have provided definitions for
+ // in <new>; exercises the operators by setting the
+ // replacement allocator to fail, and asserting that an
+ // exception is thrown or not as appropriate for the operator
+ if (1) {
+ // operator new throws
+ void* ptr = 0;
+ _RWSTD_UNUSED (ptr);
+
+ alloc.init (); // reset the allocator
+
+#ifdef _RWSTD_NO_OPERATOR_NEW_NOTHROW
+
+ // verify that the nothrow version of operator new provided
+ // by our library doesn't call the ordinary operator new
+ // (if it did it would cause recursion if a replacement operator
+ // new were to be implemented in terms of the nothrow version)
+
+ // also verify that it returns 0 on failure
+
+ // force a failure by requesting too large a block of storage
+ // size_t (~0) alone isn't good enough since it causes annoying
+ // dialog boxes to be popped up by the MSVCRTD, the MSVC runtime
+ TEST_OP_THROWS ((ptr = operator new (~0U - 4096U, std::nothrow)),
+ (ptr == 0),
+ "operator new(size_t, nothrow_t) returns 0");
+
+ rw_assert (!alloc.newCalled (), 0, __LINE__,
+ "operator new called by operator new(size_t, nothrow)");
+
+#endif // defined _RWSTD_NO_OPERATOR_NEW_NOTHROW
+
+#if defined (_RWSTD_NO_OPERATOR_DELETE_NOTHROW) && \
+ !defined (_RWSTD_NO_PLACEMENT_DELETE)
+
+ // verify that the nothrow version of operator delete provided
+ // by our library prevents exceptions from propagating
+ TEST_OP_THROWS ((operator delete (0, std::nothrow)), true,
+ "operator delete(void*, nothrow_t) doesn't throw");
+
+ // verify that the nothrow version of operator delete provided
+ // by our library doesn't call the ordinary operator delete
+ // (if it did it might cause recursion if a replacement operator
+ // delete were to be implemented in terms of the nothrow version)
+ rw_assert (!alloc.deleteCalled (), 0, __LINE__,
+ "operator delete(void*) called by "
+ "operator delete(void*, nothrow_t)");
+
+#endif // _RWSTD_NO_OPERATOR_DELETE_NOTHROW && _RWSTD_NO_PLACEMENT_DELETE
+
+#ifdef _RWSTD_NO_OPERATOR_NEW_ARRAY
+
+ // verify that the array form of operator new throws bad_alloc on
+ // failure
+ TEST_OP_THROWS ((operator new[] (1)), false,
+ "operator new[] (size_t) throws bad_alloc");
+
+ // verify that the array form of operator new provided by our
+ // library calls the ordinary operator new
+ rw_assert (alloc.newCalled (), 0, __LINE__,
+ "operator new called by operator new[](size_t)");
+
+#endif // defined _RWSTD_NO_OPERATOR_NEW_ARRAY
+
+#ifdef _RWSTD_NO_OPERATOR_NEW_ARRAY_NOTHROW
+
+ TEST_OP_THROWS ((ptr = operator new[](1, std::nothrow)),
+ (ptr == 0),
+ "operator new[] (size_t, nothrow_t) returns 0");
+
+ rw_assert (alloc.newCalled (), 0, __LINE__,
+ "operator new(size_t) called by "
+ "operator new[](size_t, nothrow_t)");
+
+#endif // defined _RWSTD_NO_OPERATOR_NEW_ARRAY_NOTHROW
+
+#ifdef _RWSTD_NO_OPERATOR_DELETE_ARRAY
+
+ TEST_OP_THROWS ((operator delete[] (0)), true,
+ "operator delete[] (void*) doesn't throw");
+
+ rw_assert (alloc.deleteCalled (), 0, __LINE__,
+ "operator delete called by operator delete[](void*)");
+
+#endif // defined _RWSTD_NO_OPERATOR_DELETE_ARRAY
+
+#if defined (_RWSTD_NO_OPERATOR_DELETE_ARRAY_NOTHROW) && \
+ !defined ( _RWSTD_NO_PLACEMENT_DELETE)
+
+ TEST_OP_THROWS ((operator delete[] (0, std::nothrow)), true,
+ "operator delete[] (void*, nothrow_t) doesn't "
+ "throw");
+
+ rw_assert (alloc.deleteCalled (), 0, __LINE__,
+ "operator delete(void*) called by "
+ "operator delete[](void*, nothrow_t)");
+
+#endif // _RWSTD_NO_OPERATOR_DELETE_ARRAY_NOTHROW &&
+ // !_RWSTD_NO_PLACEMENT_DELETE
+
+ // verify that the nothrow form of operator new provided by our
+ // library isn't recursively implemented in terms of the ordinary
+ // operator new
+ rw_assert (0 == recursive_new_nothrow, 0, __LINE__,
+ "operator new (size_t, nothrow_t) causes recursion");
+
+ rw_assert (0 == recursive_delete_nothrow, 0, __LINE__,
+ "operator delete (void*, nothrow_t) causes recursion");
+ }
+
+ // __rw_allocate() is like ::operator new() except that it calls
+ // __rw_throw() on failure (which may throw std::bad_alloc).
+ // This test checks that __rw_throw() is called,
+ // that it properly calls __rw_throw_proc(), and that bad_alloc
+ // is thrown. We'll use the replaced ::operator new() to
+ // control when a memory allocation request will fail.
+
+#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ const bool test_rw_allocate = true;
+
+#else // if defined (_RWSTD_NO_REPLACEABLE_NEW_DELETE)
+
+ // avoid tests that depend on the replacement operators new
+ // and delete on platforms like AIX or Win32 where they cannot
+ // be reliably replaced
+ const bool test_rw_allocate = false;
+
+#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
+
+ if (test_rw_allocate) {
+
+ alloc.init (); // reset the allocator
+
+ _RW::__rw_throw_proc = my_throw_proc; // set the throw func
+ my_throw_proc_called = false;
+
+ for (std::size_t i = 0; i < 10; ++i) {
+
+ char* ptr = 0;
+
+ const bool doFail = !!(i % 2); // prevent MSVC warning 4800
+ if (doFail)
+ alloc._failAlloc = true;
+
+ try {
+ // allocation
+ alloc._bytesRequested = ~i; // reset
+
+ ptr = _RWSTD_STATIC_CAST (char*, _RW::__rw_allocate (i));
+ rw_assert (alloc._bytesRequested == i, 0, __LINE__,
+ "__rw_allocate (%u) requested %u bytes",
+ i, alloc._bytesRequested);
+
+ rw_assert (alloc.newCalled (), 0, __LINE__,
+ "operator new() called");
+ rw_assert (!doFail, 0, __LINE__,
+ "allocation succeeded");
+ rw_assert (my_throw_proc_called == false,
+ 0, __LINE__,
+ "my_throw_proc called");
+
+ // deallocation
+ _RW::__rw_deallocate (ptr, i);
+
+ rw_assert (alloc.deleteCalled (),
+ 0, __LINE__,
+ "operator delete() called");
+ rw_assert (alloc._deallocPtr == ptr,
+ 0, __LINE__,
+ "allocated memory deallocated");
+
+ }
+ catch (std::bad_alloc) {
+ rw_assert (doFail, 0, __LINE__,
+ "expected bad_alloc exception");
+
+ rw_assert (my_throw_proc_called == true, 0, __LINE__,
+ "my_throw_proc called");
+ }
+ catch (...) {
+ rw_assert (false, 0, __LINE__,
+ "expected std::bad_alloc exception");
+ }
+
+ my_throw_proc_called = false;
+ }
+ }
+ else {
+ rw_warn (false, 0, __LINE__,
+ "__rw::__rw_allocate() not exercised: "
+ "_RWSTD_NO_REPLACEABLE_NEW_DELETE #defined");
+ }
+
+ return 0;
+}
+
+/**************************************************************************/
+
+
+int main (int argc, char* argv [])
+{
+ return rw_test (argc, argv, __FILE__,
+ "lib.support.dynamic",
+ 0 /* no comment */,
+ run_test,
+ "",
+ (void*)0);
+}
Propchange: stdcxx/trunk/tests/support/18.support.dynamic.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: stdcxx/trunk/tests/support/18.support.dynamic.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Added: stdcxx/trunk/tests/support/18.support.rtti.cpp
URL:
http://svn.apache.org/viewvc/stdcxx/trunk/tests/support/18.support.rtti.cpp?rev=645750&view=auto
==============================================================================
--- stdcxx/trunk/tests/support/18.support.rtti.cpp (added)
+++ stdcxx/trunk/tests/support/18.support.rtti.cpp Mon Apr 7 18:05:14 2008
@@ -0,0 +1,439 @@
+/***************************************************************************
+ *
+ * 18.support.rtti.cpp - test exercising 18.5 [lib.support.rtti]
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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.
+ *
+ * Copyright 2001-2008 Rogue Wave Software.
+ *
+ **************************************************************************/
+
+#include <rw/_defs.h>
+#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
+// Disable implicit inclusion to work around
+// a limitation in IBM's VisualAge 5.0.2.0 (see PR#26959)
+
+# define _RWSTD_NO_IMPLICIT_INCLUSION
+#endif
+
+/**************************************************************************/
+
+
+// verifies that typeid is correctly declared for MSVC (see PR #25603)
+void foo ()
+{
+ _THROW (0); // must appear before #include <typeinfo>
+}
+
+/**************************************************************************/
+
+
+#include <typeinfo>
+#include <driver.h>
+#include <valcmp.h>
+
+// polymorphic classes (10.3, p1) used in tests below
+struct B { virtual ~B () { } };
+struct D1: B { };
+struct D2: B { };
+
+/**************************************************************************/
+
+static int
+run_test (int, char* [])
+{
+ if (1) {
+ // exercise 18.5, the synopsis of <typeinfo>
+
+ std::type_info *ti = 0;
+ std::bad_cast *bc = 0;
+ std::bad_typeid *bt = 0;
+
+ _RWSTD_UNUSED (ti);
+ _RWSTD_UNUSED (bc);
+ _RWSTD_UNUSED (bt);
+ }
+
+ if (1) {
+ // exercise 18.5.1, class type_info interface
+
+ // 18.5.1, p2
+ bool (std::type_info::*p_op_eq)(const std::type_info&) const =
+ &std::type_info::operator==;
+
+ // 18.5.1, p3
+ bool (std::type_info::*p_op_neq)(const std::type_info&) const =
+ &std::type_info::operator!=;
+
+ // 18.5.1, p5
+ bool (std::type_info::*p_before)(const std::type_info&) const =
+ &std::type_info::before;
+
+ // 18.5.1, p7
+ const char* (std::type_info::*p_name)() const = &std::type_info::name;
+
+ _RWSTD_UNUSED (p_op_eq);
+ _RWSTD_UNUSED (p_op_neq);
+ _RWSTD_UNUSED (p_before);
+ _RWSTD_UNUSED (p_name);
+ }
+
+ if (1) {
+ // exercise 18.5.1, class type_info functionality
+ D1 d1;
+ D2 d2;
+
+ const std::type_info &ti_D1 = typeid (D1);
+ const std::type_info &ti_D2 = typeid (D2);
+
+ const std::type_info &ti_d1 = typeid (d1);
+ const std::type_info &ti_d2 = typeid (d2);
+
+
+ const char *D1_name = ti_D1.name () ? ti_D1.name () : "(D1 null)";
+ const char *D2_name = ti_D2.name () ? ti_D2.name () : "(D2 null)";
+ const char *d1_name = ti_d1.name () ? ti_d1.name () : "(d1 null)";
+ const char *d2_name = ti_d2.name () ? ti_d2.name () : "(d2 null)";
+
+ // 18.5.1, p2
+ rw_assert (ti_D1 == ti_D1, 0, __LINE__,
+ "std::type_info::operator==(): \"%s\" != \"%s\"",
+ D1_name, D1_name);
+ rw_assert (ti_D1 == ti_d1, 0, __LINE__,
+ "std::type_info::operator==(): \"%s\" != \"%s\"",
+ D1_name, d1_name);
+ rw_assert (!(ti_D1 == ti_D2), 0, __LINE__,
+ "std::type_info::operator==(): \"%s\" == \"%s\"",
+ D1_name, D2_name);
+ rw_assert (ti_d1 == ti_d1, 0, __LINE__,
+ "std::type_info::operator==(): \"%s\" != \"%s\"",
+ d1_name, d1_name);
+ rw_assert (ti_d1 == ti_D1, 0, __LINE__,
+ "std::type_info::operator==(): \"%s\" != \"%s\"",
+ d1_name, D1_name);
+ rw_assert (!(ti_d1 == ti_d2), 0, __LINE__,
+ "std::type_info::operator==(): \"%s\" == \"%s\"",
+ d1_name, d2_name);
+
+ // 18.5.1, p3
+ rw_assert (ti_D1 != ti_D2, 0, __LINE__,
+ "std::type_info::operator!=(): \"%s\" == \"%s\"",
+ D1_name, D2_name);
+ rw_assert (ti_D1 != ti_d2, 0, __LINE__,
+ "std::type_info::operator!=(): \"%s\" == \"%s\"",
+ D1_name, d2_name);
+ rw_assert (!(ti_D1 != ti_D1), 0, __LINE__,
+ "std::type_info::operator!=(): \"%s\" != \"%s\"",
+ D1_name, D1_name);
+ rw_assert (ti_d1 != ti_d2, 0, __LINE__,
+ "std::type_info::operator!=(): \"%s\" == \"%s\"",
+ d1_name, d2_name);
+ rw_assert (ti_d1 != ti_D2, 0, __LINE__,
+ "std::type_info::operator!=(): \"%s\" == \"%s\"",
+ d1_name, D2_name);
+ rw_assert (!(ti_d1 != ti_d1), 0, __LINE__,
+ "std::type_info::operator!=(): \"%s\" != \"%s\"",
+ d1_name, d1_name);
+
+ // 18.5.1, p5
+ rw_assert (!ti_D1.before (ti_D1) && !ti_D2.before (ti_D2),
+ 0, __LINE__, "std::type_info::before ()");
+ rw_assert (ti_D1.before (ti_D2) || ti_D2.before (ti_D1),
+ 0, __LINE__, "std::type_info::before ()");
+ rw_assert (ti_d1.before (ti_d2) || ti_d2.before (ti_d1),
+ 0, __LINE__, "std::type_info::before ()");
+ rw_assert (!ti_d1.before (ti_d1) && !ti_d2.before (ti_d2),
+ 0, __LINE__, "std::type_info::before ()");
+
+ // 18.5.1, p7
+ rw_assert (0 == rw_strncmp (D1_name, d1_name), 0, __LINE__,
+ "std::type_info::name (): \"%s\" != \"%s\"",
+ D1_name, d1_name);
+ rw_assert (0 != rw_strncmp (D1_name, D2_name), 0, __LINE__,
+ "std::type_info::name (): \"%s\" == \"%s\"",
+ D1_name, D2_name);
+ rw_assert (0 == rw_strncmp (D2_name, d2_name), 0, __LINE__,
+ "std::type_info::name (): \"%s\" != \"%s\"",
+ D2_name, d2_name);
+ rw_assert (0 != rw_strncmp (d1_name, d2_name), 0, __LINE__,
+ "std::type_info::name (): \"%s\" == \"%s\"",
+ d1_name, d2_name);
+ }
+
+ if (1) {
+ // exercise 18.5.2, class bad_cast interface
+
+ // std::bad_cast must publicly derive from std::exception
+ const std::bad_cast *pbc = 0;
+ const std::exception *pe = pbc;
+
+ // 18.5.2, p2
+ std::bad_cast bc;
+
+ // 18.5.2, p4 - copy ctor
+ std::bad_cast bc2 (bc);
+
+ // 18.5.2, p4 - assignment
+ std::bad_cast& (std::bad_cast::*p_op_assign)(const std::bad_cast&)
+ _PTR_THROWS (()) = &std::bad_cast::operator=;
+
+ // 18.5.2, p5
+ const char* (std::bad_cast::*p_what)() const _PTR_THROWS (()) =
+ &std::bad_cast::what;
+
+ _RWSTD_UNUSED (pbc);
+ _RWSTD_UNUSED (pe);
+ _RWSTD_UNUSED (bc);
+ _RWSTD_UNUSED (bc2);
+ _RWSTD_UNUSED (p_op_assign);
+ _RWSTD_UNUSED (p_what);
+ }
+
+ if (1) {
+ // exercise 18.5.2, class bad_cast functionality
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+# ifndef _RWSTD_NO_DYNAMIC_CAST
+
+ const char *caught = "no exception";
+
+ D1 d1;
+ B &b = d1;
+
+ try {
+ D2 &d2 = dynamic_cast<D2&>(b);
+
+ _RWSTD_UNUSED (d2);
+ }
+ catch (const std::bad_cast &bc) {
+ caught = "std::bad_cast";
+
+ // 18.5.2, p2
+ std::bad_cast bc2;
+
+ // 18.5.2, p4 - copy ctor
+ std::bad_cast bc3 (bc);
+
+ const char* const bc_what = bc.what ();
+ const char* bc2_what = bc2.what ();
+ const char* const bc3_what = bc3.what ();
+
+ if (0 == bc2_what)
+ rw_assert (false, 0, __LINE__, "bad_cast().what() != 0");
+
+ if (0 == bc3_what)
+ rw_assert (false, 0, __LINE__,
+ "bad_cast::what() != 0 failed "
+ "for a copy of a caught exception object");
+
+ if (bc2_what && bc3_what)
+ rw_warn (0 == rw_strncmp (bc2_what, bc3_what),
+ 0, __LINE__,
+ "bad_cast::bad_cast (const bad_cast&): "
+ "\"%s\" != \"%s\"", bc_what, bc3_what);
+
+ // 18.5.2, p4 - assignment
+ bc2 = bc;
+
+ bc2_what = bc2.what ();
+
+ if (0 == bc_what)
+ rw_assert (false, 0, __LINE__,
+ "bad_cast::what() != 0 failed "
+ "for a caught exception object");
+
+ if (0 == bc2_what)
+ rw_assert (false, 0, __LINE__,
+ "bad_cast::what() != 0 failed "
+ "for an assigned exception object");
+
+ if (bc_what && bc2_what)
+ rw_warn (0 == rw_strncmp (bc_what, bc2_what),
+ 0, __LINE__,
+ "bad_cast::operator=(const bad_cast&): "
+ "\"%s\" != \"%s\"", bc_what, bc2_what);
+
+ // 18.5.2, p5
+ if (bc_what)
+ rw_assert (0 == rw_strncmp (bc.what (), bc.what ()),
+ 0, __LINE__,
+ "bad_cast::what() const: \"%s\" != \"%s\"",
+ bc.what (), bc.what ());
+ }
+ catch (const std::exception&) {
+ caught = "std::exception";
+ }
+ catch (...) {
+ caught = "unknown exception";
+ }
+
+#if !defined (_RWSTD_NO_STD_BAD_CAST) \
+ || !defined (_RWSTD_NO_RUNTIME_IN_STD)
+
+ const char expect[] = "std::bad_cast";
+
+#else
+
+ const char expect[] = "std::bad_cast (alias for ::bad_cast)";
+
+#endif // !NO_STD_BAD_CAST || !NO_RUNTIME_IN_STD
+
+ rw_assert (0 == rw_strncmp (caught, "std::bad_cast"),
+ 0, __LINE__,
+ "dynamic_cast<>() threw %s, expected %s; this suggests "
+ "that bad_cast might be defined in the wrong namespace",
+ caught, expect);
+
+ _RWSTD_UNUSED (d1);
+ _RWSTD_UNUSED (b);
+
+# endif // _RWSTD_NO_DYNAMIC_CAST
+#endif // _RWSTD_NO_EXCEPTIONS
+ }
+
+ if (1) {
+ // exercise 18.5.3, class bad_typeid interface
+
+ // std::bad_cast must publicly derive from std::exception
+ const std::bad_typeid *pbt = 0;
+ const std::exception *pe = pbt;
+
+ // 18.5.2, p2
+ std::bad_typeid bt;
+
+ // 18.5.2, p4 - copy ctor
+ std::bad_typeid bt2 (bt);
+
+ // 18.5.2, p4 - assignment
+ std::bad_typeid& (std::bad_typeid::*p_op_assign)(const
std::bad_typeid&)
+ _PTR_THROWS (()) = &std::bad_typeid::operator=;
+
+ // 18.5.2, p5
+ const char* (std::bad_typeid::*p_what)() const _PTR_THROWS (()) =
+ &std::bad_typeid::what;
+
+ _RWSTD_UNUSED (pbt);
+ _RWSTD_UNUSED (pe);
+ _RWSTD_UNUSED (bt);
+ _RWSTD_UNUSED (bt2);
+ _RWSTD_UNUSED (p_op_assign);
+ _RWSTD_UNUSED (p_what);
+ }
+
+ if (1) {
+ // exercise 18.5.3, class bad_typeid functionality
+
+#ifndef _RWSTD_NO_EXCEPTIONS
+
+ const char *caught = "no exception";
+
+ try {
+
+#if !defined (__GNUG__) || __GNUG__ > 2
+
+ B *b = 0;
+
+ // 5.2.8, p2 - typeid(0) throws std::bad_typeid
+ const std::type_info &ti = typeid (*b);
+
+ _RWSTD_UNUSED (b);
+ _RWSTD_UNUSED (ti);
+
+#else
+
+ // working around a gcc 2.x bug
+ caught = "SIGSEGV (program dumps core)";
+
+#endif // gcc < 3.0
+
+ }
+ catch (const std::bad_typeid &bt) {
+ caught = "std::bad_typeid";
+
+ // 18.5.2, p2
+ std::bad_typeid bt2;
+
+ // 18.5.2, p4 - copy ctor
+ std::bad_typeid bt3 (bt);
+
+ // verify that what() returns the same string
+ // after copy construction
+ rw_warn (0 == rw_strncmp (bt.what (), bt3.what ()),
+ 0, __LINE__,
+ "std::bad_typeid::bad_typeid (const bad_typeid&): "
+ "\"%s\" != \"%s\"", bt.what (), bt3.what ());
+
+ // 18.5.2, p4 - assignment
+ bt2 = bt;
+
+ // verify that what() returns the same string
+ // after assignment
+ rw_warn (0 == rw_strncmp (bt.what (), bt2.what ()),
+ 0, __LINE__,
+ "std::bad_typeid::operator=(const bad_typeid&): "
+ "\"%s\" != \"%s\"", bt.what (), bt2.what ());
+
+ // 18.5.2, p5
+ rw_assert (0 == rw_strncmp (bt.what (), bt.what ()),
+ 0, __LINE__,
+ "std::bad_typeid::what() const: "
+ "\"%s\" != \"%s\"", bt.what (), bt.what ());
+ }
+ catch (const std::exception&) {
+ caught = "std::exception";
+ }
+ catch (...) {
+ caught = "unknown exception";
+ }
+
+#if !defined (_RWSTD_NO_STD_BAD_TYPEID) \
+ || !defined (_RWSTD_NO_RUNTIME_IN_STD)
+
+ const char expect[] = "std::bad_typeid";
+
+#else
+
+ const char expect[] = "std::bad_typeid (alias for ::bad_typeid)";
+
+#endif // !NO_STD_BAD_TYPEID || !NO_RUNTIME_IN_STD
+
+
+ rw_assert (0 == rw_strncmp (caught, "std::bad_typeid"),
+ 0, __LINE__,
+ "typeid ((T*)0) threw %s, expected %s; this suggests "
+ "that bad_typeid might be defined in the wrong namespace",
+ caught, expect);
+
+#endif // _RWSTD_NO_EXCEPTIONS
+ }
+
+ return 0;
+}
+
+int main (int argc, char* argv [])
+{
+ return rw_test (argc, argv, __FILE__,
+ "lib.support.rtti",
+ 0 /* no comment */,
+ run_test,
+ "",
+ (void*)0);
+}
Propchange: stdcxx/trunk/tests/support/18.support.rtti.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: stdcxx/trunk/tests/support/18.support.rtti.cpp
------------------------------------------------------------------------------
svn:keywords = Id