Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / New_Fail_Test.cpp
bloba63539c77d1d1ee78264c27871b58c99f1012d71
2 //=============================================================================
3 /**
4 * @file New_Fail_Test.cpp
6 * Checks to be sure that a failed ACE_NEW[_RETURN | _NORETURN] doesn't end
7 * up throwing an exception up to the caller.
9 * Note that this test doesn't get a real attempt on platforms which:
10 * 1. Are known to throw exceptions when 'new' runs out of resources,
11 * 2. Are built with exceptions disabled.
12 * In these cases, the test puts a message in the log noting that a failed
13 * new will throw an exception, and trust that the user accepts that risk.
15 * @author Steve Huston <shuston@riverace.com>
17 //=============================================================================
19 #include "test_config.h"
20 #include "ace/Log_Msg.h"
21 #include "ace/OS_Memory.h"
22 #include "ace/CORBA_macros.h"
23 #include "ace/Numeric_Limits.h"
25 // This test allocates all of the heap memory, forcing 'new' to fail
26 // because of a lack of memory. The ACE_NEW macros should prevent an
27 // exception from being thrown past the ACE_NEW. If this test doesn't
28 // wipe out on an alloc exception, it passes.
30 // If it doesn't ever fail an allocation, there's a warning that something is
31 // wrong. The allocated memory is always freed to avoid masking a leak
32 // somewhere else in the test.
34 // Most we can do, by half. Using max alone gets "invalid allocation size"
35 // messages on stdout on Windows.
36 static const size_t BIG_BLOCK = ACE_Numeric_Limits<size_t>::max () / 2;
38 // Shouldn't take many "as much as possible" tries to get a failure.
39 static const int MAX_ALLOCS_IN_TEST = 2;
41 static void
42 try_ace_new (char **p)
44 ACE_NEW (*p, char[BIG_BLOCK]);
45 return;
48 static char *
49 try_ace_new_return ()
51 char *p {};
52 ACE_NEW_RETURN (p, char[BIG_BLOCK], nullptr);
53 return p;
56 static char *
57 try_ace_new_noreturn ()
59 char *p {};
60 ACE_NEW_NORETURN (p, char[BIG_BLOCK]);
61 return p;
64 int
65 run_main (int, ACE_TCHAR *[])
67 ACE_START_TEST (ACE_TEXT ("New_Fail_Test"));
68 int status {};
70 char *blocks[MAX_ALLOCS_IN_TEST];
71 int i {};
73 try
75 // First part: test ACE_NEW
76 for (i = 0; i < MAX_ALLOCS_IN_TEST; i++)
78 try_ace_new (&blocks[i]);
79 if (blocks[i] == 0)
80 break;
82 if (i == MAX_ALLOCS_IN_TEST)
84 ACE_ERROR ((LM_WARNING,
85 ACE_TEXT ("Test didn't exhaust available memory\n")));
86 // Back up to valid pointer for deleting.
87 --i;
89 else
91 ACE_TEST_ASSERT (blocks[i] == 0);
92 if (errno == ENOMEM)
93 ACE_DEBUG ((LM_DEBUG,
94 ACE_TEXT ("ACE_NEW failed properly at block %d\n"),
95 i));
96 else
97 ACE_ERROR ((LM_ERROR,
98 ACE_TEXT ("ACE_NEW failed at block %d, but ")
99 ACE_TEXT ("expected ENOMEM, %p (%d)\n"),
101 ACE_TEXT ("got"),
102 ACE_ERRNO_GET));
105 // Free the memory to try ACE_NEW_RETURN
106 while (i >= 0)
107 delete [] blocks[i--];
109 // Second part: test ACE_NEW_RETURN
110 for (i = 0; i < MAX_ALLOCS_IN_TEST; i++)
112 blocks[i] = try_ace_new_return ();
113 if (blocks[i] == 0)
114 break;
117 if (i == MAX_ALLOCS_IN_TEST)
119 ACE_ERROR ((LM_WARNING,
120 ACE_TEXT ("Test didn't exhaust available memory\n")));
121 // Back up to valid pointer.
122 --i;
124 else
126 ACE_TEST_ASSERT (blocks[i] == 0);
127 if (errno == ENOMEM)
128 ACE_DEBUG ((LM_DEBUG,
129 ACE_TEXT ("ACE_NEW_RETURN failed properly at block %d\n"),
130 i));
131 else
132 ACE_ERROR ((LM_ERROR,
133 ACE_TEXT ("ACE_NEW_RETURN failed at block %d, but ")
134 ACE_TEXT ("expected ENOMEM, %p (%d)\n"),
136 ACE_TEXT ("got"),
137 ACE_ERRNO_GET));
139 while (i >= 0)
140 delete [] blocks[i--];
142 // Third part: test ACE_NEW_NORETURN
143 for (i = 0; i < MAX_ALLOCS_IN_TEST; i++)
145 blocks[i] = try_ace_new_noreturn ();
146 if (blocks[i] == 0)
147 break;
150 if (i == MAX_ALLOCS_IN_TEST)
152 ACE_ERROR ((LM_WARNING,
153 ACE_TEXT ("Test didn't exhaust available memory\n")));
154 // Back up to valid pointer.
155 --i;
157 else
159 ACE_TEST_ASSERT (blocks[i] == 0);
160 if (errno == ENOMEM)
161 ACE_DEBUG ((LM_DEBUG,
162 ACE_TEXT ("ACE_NEW_NORETURN failed properly at block %d\n"),
163 i));
164 else
165 ACE_ERROR ((LM_ERROR,
166 ACE_TEXT ("ACE_NEW_NORETURN failed at block %d, but ")
167 ACE_TEXT ("expected ENOMEM, %p (%d)\n"),
169 ACE_TEXT ("got"),
170 ACE_ERRNO_GET));
172 while (i >= 0)
173 delete [] blocks[i--];
175 catch (...)
177 ACE_ERROR ((LM_ERROR,
178 ACE_TEXT ("Caught exception during test; ")
179 ACE_TEXT ("ACE_bad_alloc not defined correctly\n")));
180 // Mark test failure
181 status = 1;
184 ACE_END_TEST;
185 return status;