first commit

This commit is contained in:
Jose Caban
2025-06-07 11:34:38 -04:00
commit 0eb2d7c07d
4708 changed files with 1500614 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
/***************************************************************************
*
* 19.cerrno.cpp - test exercising the lib.errno
*
* $Id: 19.cerrno.cpp 550991 2007-06-26 23:58:07Z sebor $
*
***************************************************************************
*
* 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 1994-2006 Rogue Wave Software.
*
**************************************************************************/
// include only <cerrno> here to prevent namespace pollution
#include <cerrno>
/**************************************************************************/
const char* const errors[] = {
#ifndef errno
"errno",
#endif // errno
#ifndef EDOM
"EDOM not defined",
#elif EDOM <= 0
"EDOM not positive",
#endif // EDOM
#ifndef EILSEQ
"EILSEQ", // lwg issue 288
#elif EILSEQ <= 0
"EILSEQ not positive",
#elif EILSEQ == EDOM
"EILSEQ not distinct from EDOM",
#endif // EILSEQ
#ifndef ERANGE
"ERANGE not defined",
#elif ERANGE <= 0
"ERANGE not positive",
#elif ERANGE == EDOM
"ERANGE not distinct from EDOM",
#elif ERANGE == EILSEQ
"ERANGE not distinct from EILSEQ",
#endif // ERANGE
0
};
/**************************************************************************/
// include all other headers here
#include <any.h> // for rw_any_t
#include <driver.h> // for rw_test(), ...
/**************************************************************************/
template <class T> void set_errno_value (T, int) { /* empty */ }
void set_errno_value (int &errno_ref, int val) { errno_ref = val; }
/**************************************************************************/
static int
errno_at_startup;
static int
run_test (int, char**)
{
rw_info (0, 0, 0, "exercising the contents of the <cerrno> header");
for (unsigned i = 0; errors [i]; ++i) {
rw_assert (0 == errors [i], 0, 0,
"macro %s", errors [i]);
}
// get the type of errno
const char* const errno_type = rw_any_t (errno).type_name ();
// 7.5, p2 of C99: the type of errno must be int
rw_assert ( 'i' == errno_type [0]
&& 'n' == errno_type [1]
&& 't' == errno_type [2]
&& '\0' == errno_type [3],
0, 0,
"the type of errno is int, got %s", errno_type);
// 7.5, p3 of C99: errno must be 0 at program startup
rw_assert (0 == errno_at_startup, 0, 0,
"errno == 0 at program startup, got %d", errno_at_startup);
#ifndef EDOM
# define EDOM 33 /* Solaris value */
#endif // EDOM
// 7.5, p2 of C99: errno must be a modifiable lvalue
set_errno_value (errno, int (EDOM));
rw_assert (EDOM == errno, 0, 0,
"errno == %d (%{#*m}, got %d (%{#m}) "
"(errno not a modifiable lvalue?)",
EDOM, EDOM, errno, errno);
#ifndef ERANGE
# define ERANGE 34 /* Solaris value */
#endif // ERANGE
set_errno_value (errno, int (ERANGE));
rw_assert (ERANGE == errno, 0, 0,
"errno == %d (%{#*m}, got %d (%{#m}) "
"(errno not a modifiable lvalue?)",
ERANGE, ERANGE, errno, errno);
#ifndef EILSEQ
# define EILSEQ 84 /* Solaris value */
#endif // EILSEQ
set_errno_value (errno, int (EILSEQ));
rw_assert (EILSEQ == errno, 0, 0,
"errno == %d (%{#*m}, got %d (%{#m}) "
"(errno not a modifiable lvalue?)",
EILSEQ, EILSEQ, errno, errno);
return 0;
}
/**************************************************************************/
int main (int argc, char *argv[])
{
errno_at_startup = errno;
return rw_test (argc, argv, __FILE__,
"lib.errno",
0 /* no comment */, run_test,
0 /* no command line options */, 0);
}

View File

@@ -0,0 +1,362 @@
/***************************************************************************
*
* 19.exceptions.mt.cpp - test exercising the thread safety
* of C++ Standard Library exception classes
*
* $Id: 19.exceptions.mt.cpp 425530 2006-07-25 21:39:50Z sebor $
*
***************************************************************************
*
* 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 2005-2006 Rogue Wave Software.
*
**************************************************************************/
#include <stdexcept> // for exceptions
#include <string> // for string
#include <cassert> // for assert
#include <cstdio> // for printf()
#include <cmdopt.h>
#include <driver.h>
#include <rw_alarm.h> // for rw_alarm()
#include <rw_thread.h> // for rw_thread_pool()
#include <valcmp.h>
/**************************************************************************/
#ifndef NTHREADS
# ifndef _RWSTD_REENTRANT
# define MAX_THREADS 0
# define NTHREADS 0
# else
# define MAX_THREADS 32
# define NTHREADS 4
# endif // _RWSTD_REENTRANT
#endif // NTHREADS
/**************************************************************************/
/* extern */ int rw_opt_nloops = 256 * 1024;
/* extern */ int rw_opt_nthreads = NTHREADS;
/**************************************************************************/
volatile int alarm_expired;
extern "C" {
static void handle_alarm (int)
{
alarm_expired = 1;
}
} // extern "C"
// string to intialize exceptions from
static const char what_buf [] = {
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789ABCDEF"
};
enum {
exception_tag,
logic_error_tag,
domain_error_tag,
invalid_argument_tag,
length_error_tag,
out_of_range_tag,
runtime_error_tag,
range_error_tag,
overflow_error_tag,
underflow_error_tag,
Derived_tag
};
struct DerivedException: std::invalid_argument
{
DerivedException (const char *str)
: std::invalid_argument (str) { }
};
static void
throw_exception (unsigned which, const char *what)
{
switch (which) {
case exception_tag: throw std::exception ();
case logic_error_tag: throw std::logic_error (what);
case domain_error_tag: throw std::domain_error (what);
case invalid_argument_tag: throw std::invalid_argument (what);
case length_error_tag: throw std::length_error (what);
case out_of_range_tag: throw std::out_of_range (what);
case runtime_error_tag: throw std::runtime_error (what);
case range_error_tag: throw std::range_error (what);
case overflow_error_tag: throw std::overflow_error (what);
case underflow_error_tag: throw std::underflow_error (what);
case Derived_tag: throw DerivedException (what);
default: _RWSTD_ASSERT (!"logic error: bad exception tag");
}
}
/**************************************************************************/
extern "C" void*
test_single_exception (void *arg)
{
const rw_thread_t* const tid = (rw_thread_t*)arg;
std::printf ("thread procedure %ld starting...\n", tid->threadno);
for (unsigned i = 0; i < unsigned (rw_opt_nloops); ++i) {
if (alarm_expired)
break;
const std::size_t what_len = std::size_t (i % 1024);
const char* const what = what_buf + sizeof what_buf - what_len - 1;
const unsigned thrown = i % 11;
unsigned caught = _RWSTD_UINT_MAX;
try {
// construct and throw an exception object of one
// of the predefined standard exception classes
// initialized with a distinct what string
throw_exception (thrown, what);
}
catch (DerivedException ex) {
// catch the exception object by value and verify
// that the pointer returned by what() compares
// equal to the string the thrown object was
// constructed with
caught = Derived_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::domain_error ex) {
caught = domain_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::invalid_argument ex) {
caught = invalid_argument_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::length_error ex) {
caught = length_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::out_of_range ex) {
caught = out_of_range_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::range_error ex) {
caught = range_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::overflow_error ex) {
caught = overflow_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::underflow_error ex) {
caught = underflow_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::logic_error ex) {
caught = logic_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::runtime_error ex) {
caught = runtime_error_tag;
assert (0 == rw_strncmp (ex.what (), what));
}
catch (std::exception ex) {
caught = exception_tag;
rw_strncmp (ex.what (), what);
}
// verify that an object of the thrown type was caught
assert (caught == thrown);
}
return 0;
}
/**************************************************************************/
static void
test_multi (unsigned i, unsigned nactive)
{
const std::size_t what_len = (i + nactive) % sizeof what_buf;
const char* const what = what_buf + sizeof what_buf - what_len - 1;
const unsigned thrown = (i + nactive) % 10 + 1;
try {
// construct and throw an exception object of a distinct type
// with a distinct what string at each level of recursion
throw_exception (thrown, what);
}
catch (std::exception &ex) {
// recursively throw another exception while the caught
// exception object is still active
if (nactive)
test_multi (i, nactive - 1);
// verify that the caught object's what string matches
// the string the object was originally constructed with
assert (0 == rw_strncmp (ex.what (), what));
}
}
extern "C" void*
test_multi_exceptions (void *arg)
{
const rw_thread_t* const tid = (rw_thread_t*)arg;
std::printf ("thread procedure %ld starting...\n", tid->threadno);
for (unsigned i = 0; i < unsigned (rw_opt_nloops); ++i) {
if (alarm_expired)
break;
// exercise up to 4 simultaneously active exceptions
test_multi (i, i % 4);
}
return 0;
}
/**************************************************************************/
static int
run_test (int, char**)
{
// get the current alarm (if any) set for the test
// on the command line without resetting it
const unsigned max_sec = rw_alarm (0, rw_sig_hold);
// compute a shorter timeout for each of the two subtests
const unsigned nsec = 3 < max_sec ? max_sec / 2 : 0;
rw_info (0, 0, 0,
"single active exception per thread"
"%{?}; timeout in %u seconds%{;}",
0 != max_sec, nsec ? nsec : max_sec);
// set a shorter alarm if possible
if (nsec) {
alarm_expired = 0;
rw_alarm (nsec, handle_alarm);
}
const std::size_t nthreads = std::size_t (rw_opt_nthreads);
#if 0 < NTHREADS
rw_fatal (0 == rw_thread_pool (0, nthreads, 0, test_single_exception, 0),
0, __LINE__, "rw_thread_pool() failed");
#else // if !(0 < NTHREADS)
rw_thread_t tid = rw_thread_t ();
test_single_exception (&tid);
#endif // NTHREADS
rw_info (0, 0, 0,
"multiple active exceptions per thread"
"%{?}; timeout in %u seconds%{;}",
0 != max_sec, nsec ? nsec : max_sec);
// set another shorter alarm if possible
if (nsec) {
alarm_expired = 0;
rw_alarm (nsec, handle_alarm);
}
#if 0 < NTHREADS
rw_fatal (0 == rw_thread_pool (0, nthreads, 0, test_multi_exceptions, 0),
0, __LINE__, "rw_thread_pool() failed");
#else // if !(0 < NTHREADS)
test_multi_exceptions (&tid);
#endif // NTHREADS
// restore the original alarm to go off approximately
// when the original alar would have if it hadn't been
// replaced above
if (nsec)
rw_alarm (2 * nsec, rw_sig_restore);
return 0;
}
/**************************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"lib.std.exceptions",
"thread safety", run_test,
"|-nloops#0 " // must be non-negative
"|-nthreads#0-*", // must be in [0, MAX_THREADS]
&rw_opt_nloops,
int (MAX_THREADS),
&rw_opt_nthreads);
}

View File

@@ -0,0 +1,475 @@
/***************************************************************************
*
* 19.std.exceptions.cpp - test exercising [lib.std.exceptions]
*
* $Id: 19.std.exceptions.cpp 648752 2008-04-16 17:01:56Z faridz $
*
***************************************************************************
*
* 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;
#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 directly from a program: 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 directly "
"from a program",
sizeof long_str);
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
}
_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);
}