https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fe36f081c75a0d35aea4e…
commit fe36f081c75a0d35aea4ea9a83640f970f7170ff
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sat Oct 31 11:08:27 2020 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Oct 31 11:08:27 2020 +0100
[COMPILER_APITEST] Add SEH tests from MS (#2435)
* [COMPILER_APITEST] Import MS EH/SEH tests
Taken from
https://github.com/microsoft/compiler-tests
* [CRT] Add missing declaration of _longjmpex
* [COMPILER_APITEST] Add cmake build files for MS SEH test
It is built as a static library
* [COMPILER_APITEST] Fix GCC build of MS SEH tests
There are a number of hacks in there now. Also the volatile hacks should be separated
and sent upstream.
* [COMPILER_APITEST] Fix x64 build of MS SEH tests
* [COMPILER_APITEST] Fix clang build of MS SEH tests
* [COMPILER_APITEST] Include MS SEH tests
---
modules/rostests/apitests/compiler/CMakeLists.txt | 5 +-
.../rostests/apitests/compiler/ms/CMakeLists.txt | 2 +
modules/rostests/apitests/compiler/ms/LICENSE.TXT | 21 +
modules/rostests/apitests/compiler/ms/README.md | 28 +
modules/rostests/apitests/compiler/ms/changes.txt | 11 +
.../rostests/apitests/compiler/ms/eh/ehframes.cpp | 552 +
.../rostests/apitests/compiler/ms/eh/ehframes.out | 67 +
.../rostests/apitests/compiler/ms/eh/ehthrow.amd64 | 676 +
.../rostests/apitests/compiler/ms/eh/ehthrow.arm | 676 +
.../rostests/apitests/compiler/ms/eh/ehthrow.cxx | 547 +
.../rostests/apitests/compiler/ms/eh/ehthrow.out | 676 +
.../rostests/apitests/compiler/ms/eh/ihateeh.cxx | 199 +
.../apitests/compiler/ms/eh/ihateeh.out.correct | 73231 +++++++++++++++++++
.../rostests/apitests/compiler/ms/eh/nesttry.cxx | 38 +
.../rostests/apitests/compiler/ms/eh/nesttry.out | 7 +
.../rostests/apitests/compiler/ms/eh/noreturn.cpp | 54 +
.../apitests/compiler/ms/eh/recursive_throw.cpp | 77 +
.../apitests/compiler/ms/eh/recursive_throw.out | 21 +
.../rostests/apitests/compiler/ms/eh/rethrow1.cpp | 44 +
.../rostests/apitests/compiler/ms/eh/rethrow1.out | 9 +
.../rostests/apitests/compiler/ms/eh/rethrow4.cpp | 44 +
.../rostests/apitests/compiler/ms/eh/rethrow4.out | 9 +
.../rostests/apitests/compiler/ms/eh/rethrow5.cpp | 43 +
.../rostests/apitests/compiler/ms/eh/rethrow5.out | 6 +
.../apitests/compiler/ms/eh/rethrow_unknown.cpp | 58 +
.../rostests/apitests/compiler/ms/eh/runtest.cmd | 71 +
.../rostests/apitests/compiler/ms/eh/terminate.cpp | 123 +
.../rostests/apitests/compiler/ms/eh/terminate.out | 11 +
.../apitests/compiler/ms/eh/unreachedeh.cpp | 17 +
.../rostests/apitests/compiler/ms/eh/vcatch.cpp | 57 +
.../apitests/compiler/ms/seh/CMakeLists.txt | 26 +
.../rostests/apitests/compiler/ms/seh/clean.cmd | 122 +
.../rostests/apitests/compiler/ms/seh/runtests.cmd | 196 +
modules/rostests/apitests/compiler/ms/seh/seh.h | 31 +
.../rostests/apitests/compiler/ms/seh/seh0001.c | 31 +
.../rostests/apitests/compiler/ms/seh/seh0002.c | 36 +
.../rostests/apitests/compiler/ms/seh/seh0003.c | 34 +
.../rostests/apitests/compiler/ms/seh/seh0004.c | 33 +
.../rostests/apitests/compiler/ms/seh/seh0005.c | 38 +
.../rostests/apitests/compiler/ms/seh/seh0006.c | 55 +
.../rostests/apitests/compiler/ms/seh/seh0007.c | 56 +
.../rostests/apitests/compiler/ms/seh/seh0008.c | 42 +
.../rostests/apitests/compiler/ms/seh/seh0009.c | 46 +
.../rostests/apitests/compiler/ms/seh/seh0010.c | 57 +
.../rostests/apitests/compiler/ms/seh/seh0011.c | 64 +
.../rostests/apitests/compiler/ms/seh/seh0012.c | 50 +
.../rostests/apitests/compiler/ms/seh/seh0013.c | 69 +
.../rostests/apitests/compiler/ms/seh/seh0014.c | 49 +
.../rostests/apitests/compiler/ms/seh/seh0015.c | 48 +
.../rostests/apitests/compiler/ms/seh/seh0016.c | 56 +
.../rostests/apitests/compiler/ms/seh/seh0017.c | 46 +
.../rostests/apitests/compiler/ms/seh/seh0018.c | 62 +
.../rostests/apitests/compiler/ms/seh/seh0019.c | 59 +
.../rostests/apitests/compiler/ms/seh/seh0020.c | 35 +
.../rostests/apitests/compiler/ms/seh/seh0021.c | 43 +
.../rostests/apitests/compiler/ms/seh/seh0022.c | 47 +
.../rostests/apitests/compiler/ms/seh/seh0023.c | 49 +
.../rostests/apitests/compiler/ms/seh/seh0024.c | 87 +
.../rostests/apitests/compiler/ms/seh/seh0025.c | 85 +
.../rostests/apitests/compiler/ms/seh/seh0026.c | 77 +
.../rostests/apitests/compiler/ms/seh/seh0027.c | 91 +
.../rostests/apitests/compiler/ms/seh/seh0028.c | 42 +
.../rostests/apitests/compiler/ms/seh/seh0029.c | 70 +
.../rostests/apitests/compiler/ms/seh/seh0030.c | 39 +
.../rostests/apitests/compiler/ms/seh/seh0031.c | 45 +
.../rostests/apitests/compiler/ms/seh/seh0032.c | 44 +
.../rostests/apitests/compiler/ms/seh/seh0033.c | 56 +
.../rostests/apitests/compiler/ms/seh/seh0034.c | 48 +
.../rostests/apitests/compiler/ms/seh/seh0035.c | 55 +
.../rostests/apitests/compiler/ms/seh/seh0036.c | 51 +
.../rostests/apitests/compiler/ms/seh/seh0037.c | 38 +
.../rostests/apitests/compiler/ms/seh/seh0038.c | 42 +
.../rostests/apitests/compiler/ms/seh/seh0039.c | 43 +
.../rostests/apitests/compiler/ms/seh/seh0040.c | 57 +
.../rostests/apitests/compiler/ms/seh/seh0041.c | 48 +
.../rostests/apitests/compiler/ms/seh/seh0042.c | 56 +
.../rostests/apitests/compiler/ms/seh/seh0043.c | 55 +
.../rostests/apitests/compiler/ms/seh/seh0044.c | 52 +
.../rostests/apitests/compiler/ms/seh/seh0045.c | 50 +
.../rostests/apitests/compiler/ms/seh/seh0046.c | 56 +
.../rostests/apitests/compiler/ms/seh/seh0047.c | 55 +
.../rostests/apitests/compiler/ms/seh/seh0048.c | 52 +
.../rostests/apitests/compiler/ms/seh/seh0049.c | 60 +
.../rostests/apitests/compiler/ms/seh/seh0050.c | 52 +
.../rostests/apitests/compiler/ms/seh/seh0051.c | 39 +
.../rostests/apitests/compiler/ms/seh/seh0052.c | 41 +
.../rostests/apitests/compiler/ms/seh/seh0053.c | 45 +
.../rostests/apitests/compiler/ms/seh/seh0054.c | 56 +
.../rostests/apitests/compiler/ms/seh/seh0055.c | 51 +
.../rostests/apitests/compiler/ms/seh/seh0056.c | 40 +
.../rostests/apitests/compiler/ms/seh/seh0057.c | 40 +
.../rostests/apitests/compiler/ms/seh/seh0058.c | 38 +
.../apitests/compiler/ms/seh/seh_noreturn.c | 25 +
.../apitests/compiler/ms/seh/sehframes.cpp | 974 +
.../apitests/compiler/ms/seh/sehframes.out | 99 +
modules/rostests/apitests/compiler/ms/seh/xcpt4u.c | 3463 +
.../apitests/compiler/ms/seh/xcpt4u.correct | 89 +
.../rostests/apitests/compiler/ms/seh/xcpt4u.out | 89 +
.../apitests/compiler/ms/seh/xcpt4u.test.out | 89 +
modules/rostests/apitests/compiler/ms_seh.c | 144 +
modules/rostests/apitests/compiler/testlist.c | 2 +
sdk/include/crt/setjmpex.h | 1 +
102 files changed, 85690 insertions(+), 1 deletion(-)
diff --git a/modules/rostests/apitests/compiler/CMakeLists.txt
b/modules/rostests/apitests/compiler/CMakeLists.txt
index 1cff26dbe19..7bd2a6a6b22 100644
--- a/modules/rostests/apitests/compiler/CMakeLists.txt
+++ b/modules/rostests/apitests/compiler/CMakeLists.txt
@@ -1,12 +1,15 @@
+add_subdirectory(ms)
+
list(APPEND SOURCE
+ ms_seh.c
pseh.c
pseh_cpp.cpp
psehtest2.c
testlist.c)
add_executable(compiler_apitest ${SOURCE})
-target_link_libraries(compiler_apitest wine ${PSEH_LIB})
+target_link_libraries(compiler_apitest ms_seh_test wine ${PSEH_LIB})
set_module_type(compiler_apitest win32cui)
add_importlibs(compiler_apitest msvcrt kernel32 ntdll)
add_rostests_file(TARGET compiler_apitest)
diff --git a/modules/rostests/apitests/compiler/ms/CMakeLists.txt
b/modules/rostests/apitests/compiler/ms/CMakeLists.txt
new file mode 100644
index 00000000000..0e707316d3f
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/CMakeLists.txt
@@ -0,0 +1,2 @@
+
+add_subdirectory(seh)
diff --git a/modules/rostests/apitests/compiler/ms/LICENSE.TXT
b/modules/rostests/apitests/compiler/ms/LICENSE.TXT
new file mode 100644
index 00000000000..7bb386e6f7e
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/LICENSE.TXT
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/modules/rostests/apitests/compiler/ms/README.md
b/modules/rostests/apitests/compiler/ms/README.md
new file mode 100644
index 00000000000..678ae8ceaec
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/README.md
@@ -0,0 +1,28 @@
+Microsoft compiler-tests
+========================
+
+Introduction
+------------
+This repo includes selected tests from the Microsoft compiler-tests directory.
+The initial focus is on exception handling tests, both for C++EH and SEH, to make it
easier to test WinEH implementations for compatibility with the platform. The expectation
is that this set of tests will grow and ultimately be added to the LLVM test-suite.
Opening this as a separate repo is intended as a stop gap as the work to get the LLVM
test-suite to run clean on Windows progresses.
+
+Supported Platforms
+-------------------
+The first round of tests being opened are EH, the bulk of which are SEH tests. This is
naturally Windows specific. Additionally only the most rudimentary harness is included
(runtests.cmd) due to our objective to move these tests into the LLVM harness.
+
+Quick Start
+-----------
+There are two main sub directories in the compiler-tests directory. The descriptions of
what they contain are listed below. Overtime we expect to open more tests in these
directories as well as add new areas of testing.
+
+####EH (C++EH)
+Only one test is included here now, ihateeh.cxx. This tests object destructor semantics
on Windows. Compile the file with usual flag combinations (MSVC) and compare with the
output file ihateeh.out.correct.
+
+####SEH
+The main tests in this directory are sehframes.cpp which tests various funclet frames,
and xcpt4u.c which is a large collection of SEH torture tests. This last test is one of
the main litmus tests used to verify that a compiler supports SEH suffiently to be used in
the Windows kernel. Remaining sehxxxx.c tests are particular break outs from xcpt4u.c for
ease of debugging.
+
+- Run the runtest.cmd in the seh directory to build the tests with MSVC.
+- Run the clean.cmd to clean up obj/exes left after running the tests.
+
+Next Steps
+----------
+More tests will follow. If there are particular areas where there are questions please
open an issue and we'll see if there are tests that can meet the need.
diff --git a/modules/rostests/apitests/compiler/ms/changes.txt
b/modules/rostests/apitests/compiler/ms/changes.txt
new file mode 100644
index 00000000000..03e47affad4
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/changes.txt
@@ -0,0 +1,11 @@
+Outline of changes from the old legacy tree to clean up for the open.
+
+all
+- Removed commented out legacy code hooking to the old test.h system.
+- Formated to LLVM style.
+
+xcpt4u.c
+- Cleaned up old comments refering to old products/bug numbers.
+
+ihateeh.cxx
+- Switched main to return int.
diff --git a/modules/rostests/apitests/compiler/ms/eh/ehframes.cpp
b/modules/rostests/apitests/compiler/ms/eh/ehframes.cpp
new file mode 100644
index 00000000000..3d1684dc2b6
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ehframes.cpp
@@ -0,0 +1,552 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for
+// full license information.
+
+/*
+ * Exercise lots of different kinds of C++ EH frames. Compile this with
+ * every combination of opts you can to stress the C++ EH frame code in the
+ * backend.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+
+#ifndef ALIGN
+#define ALIGN 64
+#endif
+
+extern int TestFunc(int, ...);
+
+int failures;
+
+int global;
+bool TestFuncThrows;
+
+struct SmallObj
+{
+ virtual ~SmallObj()
+ {
+ TestFunc(1, this);
+ };
+
+ int x;
+};
+
+struct BigObj
+{
+ virtual ~BigObj()
+ {
+ TestFunc(1, this);
+ };
+
+ char x[4096];
+};
+
+int Simple(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ SmallObj f;
+ return TestFunc(1, &f, &res, &arg);
+}
+
+int Try(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ SmallObj f;
+ try {
+ res = TestFunc(1, &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &f, &res, &arg);
+ }
+ return res;
+}
+
+int GSCookie(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ SmallObj f;
+ return TestFunc(1, buf, &f, &res, &arg);
+}
+
+int TryAndGSCookie(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ SmallObj f;
+ try {
+ res = TestFunc(1, &buf, &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &buf, &f, &res, &arg);
+ }
+ return res;
+}
+
+int Align(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ return TestFunc(1, d, &f, &res, &arg);
+}
+
+int TryAndAlign(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ try {
+ res = TestFunc(1, d, &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, d, &f, &res, &arg);
+ }
+ return res;
+}
+
+int GSCookieAndAlign(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ return TestFunc(1, buf, d, &f, &res, &arg);
+}
+
+int TryAndGSCookieAndAlign(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ try {
+ res = TestFunc(1, buf, d, &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, buf, d, &f, &res, &arg);
+ }
+ return res;
+}
+
+int Alloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ SmallObj f;
+ return TestFunc(1, _alloca(global), &f, &res, &arg);
+}
+
+int TryAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ SmallObj f;
+ try {
+ res = TestFunc(1, _alloca(global), &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &f, &res, &arg);
+ }
+ return res;
+}
+
+int GSCookieAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ SmallObj f;
+ return TestFunc(1, buf, _alloca(global), &f, &res, &arg);
+}
+
+int TryAndGSCookieAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ SmallObj f;
+ try {
+ res = TestFunc(1, &buf, _alloca(global), &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &buf, &f, &res, &arg);
+ }
+ return res;
+}
+
+int AlignAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ return TestFunc(1, d, _alloca(global), &f, &res, &arg);
+}
+
+int TryAndAlignAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ try {
+ res = TestFunc(1, d, _alloca(global), &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, d, &f, &res, &arg);
+ }
+ return res;
+}
+
+int GSCookieAndAlignAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ return TestFunc(1, buf, d, _alloca(global), &f, &res, &arg);
+}
+
+int TryAndGSCookieAndAlignAndAlloca(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ SmallObj f;
+ try {
+ res = TestFunc(1, buf, d, _alloca(global), &f, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, buf, d, &f, &res, &arg);
+ }
+ return res;
+}
+
+/* The *AndBigLocals set of functions try to trigger EBP adjustment */
+
+int BigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ BigObj f1;
+ return TestFunc(1, &f1, &res, &res, &res, &res, &res,
&arg);
+}
+
+int TryAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ BigObj f1;
+ try {
+ res = TestFunc(1, &f1, &res, &res, &res, &res, &res,
&arg);
+ } catch (double) {
+ res = TestFunc(2, &f1, &res, &res, &res, &res, &res,
&arg);
+ }
+ return res;
+}
+
+int GSCookieAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ BigObj f1;
+ return TestFunc(1, buf, &f1, &res, &res, &res, &res, &res,
&arg);
+}
+
+int TryAndGSCookieAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ BigObj f1;
+ try {
+ res = TestFunc(1, &buf, &f1, &res, &res, &res, &res,
&res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &buf, &f1, &res, &res, &res, &res,
&res, &arg);
+ }
+ return res;
+}
+
+int AlignAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ return TestFunc(1, d, &f1, &res, &res, &res, &res, &res,
&arg);
+}
+
+int TryAndAlignAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ try {
+ res = TestFunc(1, d, &f1, &res, &res, &res, &res, &res,
&arg);
+ } catch (double) {
+ res = TestFunc(2, d, &f1, &res, &res, &res, &res, &res,
&arg);
+ }
+ return res;
+}
+
+int GSCookieAndAlignAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ return TestFunc(1, buf, d, &f1, &res, &res, &res, &res, &res,
&arg);
+}
+
+int TryAndGSCookieAndAlignAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ try {
+ res = TestFunc(1, buf, d, &f1, &res, &res, &res, &res,
&res, &arg);
+ } catch (double) {
+ res = TestFunc(2, buf, d, &f1, &res, &res, &res, &res,
&res, &arg);
+ }
+ return res;
+}
+
+int AllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ BigObj f1;
+ return TestFunc(1, _alloca(global), &f1, &res, &res, &res, &res,
&res, &arg);
+}
+
+int TryAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ BigObj f1;
+ try {
+ res = TestFunc(1, _alloca(global), &f1, &res, &res, &res,
&res, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &f1, &res, &res, &res, &res, &res,
&arg);
+ }
+ return res;
+}
+
+int GSCookieAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ BigObj f1;
+ return TestFunc(1, buf, _alloca(global), &f1, &res, &res, &res,
&res, &res, &arg);
+}
+
+int TryAndGSCookieAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ BigObj f1;
+ try {
+ res = TestFunc(1, &buf, _alloca(global), &f1, &res, &res,
&res, &res, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, &buf, &f1, &res, &res, &res, &res,
&res, &arg);
+ }
+ return res;
+}
+
+int AlignAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ return TestFunc(1, d, _alloca(global), &f1, &res, &res, &res,
&res, &res, &arg);
+}
+
+int TryAndAlignAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ try {
+ res = TestFunc(1, d, _alloca(global), &f1, &res, &res, &res,
&res, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, d, &f1, &res, &res, &res, &res, &res,
&arg);
+ }
+ return res;
+}
+
+int GSCookieAndAlignAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ return TestFunc(1, buf, d, _alloca(global), &f1, &res, &res, &res,
&res, &res, &arg);
+}
+
+int TryAndGSCookieAndAlignAndAllocaAndBigLocals(int arg)
+{
+ puts(__FUNCTION__);
+ int res = 0;
+ char buf[16];
+ __declspec(align(ALIGN)) double d[4];
+ BigObj f1;
+ try {
+ res = TestFunc(1, buf, d, _alloca(global), &f1, &res, &res, &res,
&res, &res, &arg);
+ } catch (double) {
+ res = TestFunc(2, buf, d, &f1, &res, &res, &res, &res,
&res, &arg);
+ }
+ return res;
+}
+
+__declspec(noinline)
+int TestFunc(int, ...)
+{
+ if (TestFuncThrows)
+ {
+ TestFuncThrows = false;
+ throw 123;
+ }
+
+ return global;
+}
+
+void RunTests()
+{
+ puts("Test pass 1 - no throws");
+
+ try
+ {
+ Simple(1);
+ Try(1);
+ GSCookie(1);
+ TryAndGSCookie(1);
+ Align(1);
+ TryAndAlign(1);
+ GSCookieAndAlign(1);
+ TryAndGSCookieAndAlign(1);
+ Alloca(1);
+ TryAndAlloca(1);
+ GSCookieAndAlloca(1);
+ TryAndGSCookieAndAlloca(1);
+ AlignAndAlloca(1);
+ TryAndAlignAndAlloca(1);
+ GSCookieAndAlignAndAlloca(1);
+ TryAndGSCookieAndAlignAndAlloca(1);
+ BigLocals(1);
+ TryAndBigLocals(1);
+ GSCookieAndBigLocals(1);
+ TryAndGSCookieAndBigLocals(1);
+ AlignAndBigLocals(1);
+ TryAndAlignAndBigLocals(1);
+ GSCookieAndAlignAndBigLocals(1);
+ TryAndGSCookieAndAlignAndBigLocals(1);
+ AllocaAndBigLocals(1);
+ TryAndAllocaAndBigLocals(1);
+ GSCookieAndAllocaAndBigLocals(1);
+ TryAndGSCookieAndAllocaAndBigLocals(1);
+ AlignAndAllocaAndBigLocals(1);
+ TryAndAlignAndAllocaAndBigLocals(1);
+ GSCookieAndAlignAndAllocaAndBigLocals(1);
+ TryAndGSCookieAndAlignAndAllocaAndBigLocals(1);
+ }
+ catch (...)
+ {
+ puts("ERROR - throw not expected");
+ ++failures;
+ }
+
+ puts("Test pass 2 - throws");
+
+ for (int i = 0; i < 32; ++i)
+ {
+ TestFuncThrows = true;
+ bool caught = false;
+ try
+ {
+ switch (i)
+ {
+ case 0: Simple(1); break;
+ case 1: Try(1); break;
+ case 2: GSCookie(1); break;
+ case 3: TryAndGSCookie(1); break;
+ case 4: Align(1); break;
+ case 5: TryAndAlign(1); break;
+ case 6: GSCookieAndAlign(1); break;
+ case 7: TryAndGSCookieAndAlign(1); break;
+ case 8: Alloca(1); break;
+ case 9: TryAndAlloca(1); break;
+ case 10: GSCookieAndAlloca(1); break;
+ case 11: TryAndGSCookieAndAlloca(1); break;
+ case 12: AlignAndAlloca(1); break;
+ case 13: TryAndAlignAndAlloca(1); break;
+ case 14: GSCookieAndAlignAndAlloca(1); break;
+ case 15: TryAndGSCookieAndAlignAndAlloca(1); break;
+ case 16: BigLocals(1); break;
+ case 17: TryAndBigLocals(1); break;
+ case 18: GSCookieAndBigLocals(1); break;
+ case 19: TryAndGSCookieAndBigLocals(1); break;
+ case 20: AlignAndBigLocals(1); break;
+ case 21: TryAndAlignAndBigLocals(1); break;
+ case 22: GSCookieAndAlignAndBigLocals(1); break;
+ case 23: TryAndGSCookieAndAlignAndBigLocals(1); break;
+ case 24: AllocaAndBigLocals(1); break;
+ case 25: TryAndAllocaAndBigLocals(1); break;
+ case 26: GSCookieAndAllocaAndBigLocals(1); break;
+ case 27: TryAndGSCookieAndAllocaAndBigLocals(1); break;
+ case 28: AlignAndAllocaAndBigLocals(1); break;
+ case 29: TryAndAlignAndAllocaAndBigLocals(1); break;
+ case 30: GSCookieAndAlignAndAllocaAndBigLocals(1); break;
+ case 31: TryAndGSCookieAndAlignAndAllocaAndBigLocals(1); break;
+ }
+ }
+ catch (int)
+ {
+ caught = true;
+ }
+
+ if (!caught)
+ {
+ puts("ERROR - did not catch expected thrown object");
+ ++failures;
+ }
+ }
+}
+
+int main()
+{
+ __try
+ {
+ RunTests();
+ }
+ __except (1)
+ {
+ puts("ERROR - Unexpectedly caught an exception");
+ ++failures;
+ }
+
+ if (failures)
+ {
+ printf("Test failed with %d failure%s\n",
+ failures, failures == 1 ? "" : "s");
+ }
+ else
+ {
+ puts("Test passed");
+ }
+
+ return failures;
+}
diff --git a/modules/rostests/apitests/compiler/ms/eh/ehframes.out
b/modules/rostests/apitests/compiler/ms/eh/ehframes.out
new file mode 100644
index 00000000000..bf9dd82b8b9
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ehframes.out
@@ -0,0 +1,67 @@
+Test pass 1 - no throws
+Simple
+Try
+GSCookie
+TryAndGSCookie
+Align
+TryAndAlign
+GSCookieAndAlign
+TryAndGSCookieAndAlign
+Alloca
+TryAndAlloca
+GSCookieAndAlloca
+TryAndGSCookieAndAlloca
+AlignAndAlloca
+TryAndAlignAndAlloca
+GSCookieAndAlignAndAlloca
+TryAndGSCookieAndAlignAndAlloca
+BigLocals
+TryAndBigLocals
+GSCookieAndBigLocals
+TryAndGSCookieAndBigLocals
+AlignAndBigLocals
+TryAndAlignAndBigLocals
+GSCookieAndAlignAndBigLocals
+TryAndGSCookieAndAlignAndBigLocals
+AllocaAndBigLocals
+TryAndAllocaAndBigLocals
+GSCookieAndAllocaAndBigLocals
+TryAndGSCookieAndAllocaAndBigLocals
+AlignAndAllocaAndBigLocals
+TryAndAlignAndAllocaAndBigLocals
+GSCookieAndAlignAndAllocaAndBigLocals
+TryAndGSCookieAndAlignAndAllocaAndBigLocals
+Test pass 2 - throws
+Simple
+Try
+GSCookie
+TryAndGSCookie
+Align
+TryAndAlign
+GSCookieAndAlign
+TryAndGSCookieAndAlign
+Alloca
+TryAndAlloca
+GSCookieAndAlloca
+TryAndGSCookieAndAlloca
+AlignAndAlloca
+TryAndAlignAndAlloca
+GSCookieAndAlignAndAlloca
+TryAndGSCookieAndAlignAndAlloca
+BigLocals
+TryAndBigLocals
+GSCookieAndBigLocals
+TryAndGSCookieAndBigLocals
+AlignAndBigLocals
+TryAndAlignAndBigLocals
+GSCookieAndAlignAndBigLocals
+TryAndGSCookieAndAlignAndBigLocals
+AllocaAndBigLocals
+TryAndAllocaAndBigLocals
+GSCookieAndAllocaAndBigLocals
+TryAndGSCookieAndAllocaAndBigLocals
+AlignAndAllocaAndBigLocals
+TryAndAlignAndAllocaAndBigLocals
+GSCookieAndAlignAndAllocaAndBigLocals
+TryAndGSCookieAndAlignAndAllocaAndBigLocals
+Test passed
diff --git a/modules/rostests/apitests/compiler/ms/eh/ehthrow.amd64
b/modules/rostests/apitests/compiler/ms/eh/ehthrow.amd64
new file mode 100644
index 00000000000..97dd80befd9
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ehthrow.amd64
@@ -0,0 +1,676 @@
+
+Test #1
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A copy ctor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+Throwing
+B ctor. i = 6
+B ctor. i = 7
+A copy ctor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+B ctor. i = 9
+B ctor. i = 10
+A copy ctor. i = 11
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 12
+B ctor. i = 13
+A dtor. i = 5
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 2
+B dtor. i = 15
+B dtor. i = 14
+B dtor. i = 1
+B ctor. i = 16
+B ctor. i = 17
+A dtor. i = 0
+B dtor. i = 17
+B dtor. i = 16
+In main's catch
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 11
+B dtor. i = 19
+B dtor. i = 18
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 8
+B dtor. i = 21
+B dtor. i = 20
+
+
+Test #2
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+Throwing
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 6
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 3
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 2
+B dtor. i = 18
+B dtor. i = 17
+In catch;
+A ctor. i = 19
+Rethrowing
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 19
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 12
+B dtor. i = 23
+B dtor. i = 22
+B ctor. i = 24
+B ctor. i = 25
+A copy ctor. i = 26
+B dtor. i = 25
+B dtor. i = 24
+B dtor. i = 1
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 0
+B dtor. i = 28
+B dtor. i = 27
+In main's catch
+B ctor. i = 29
+B ctor. i = 30
+A dtor. i = 26
+B dtor. i = 30
+B dtor. i = 29
+B ctor. i = 31
+B ctor. i = 32
+A dtor. i = 9
+B dtor. i = 32
+B dtor. i = 31
+
+
+Test #3
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+Throwing
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 6
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 3
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 2
+B dtor. i = 18
+B dtor. i = 17
+In catch
+A ctor. i = 19
+Throwing new a
+B ctor. i = 20
+B ctor. i = 21
+A copy ctor. i = 22
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 23
+B ctor. i = 24
+A copy ctor. i = 25
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 19
+B dtor. i = 27
+B dtor. i = 26
+B ctor. i = 28
+B ctor. i = 29
+A dtor. i = 12
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 30
+B ctor. i = 31
+A dtor. i = 9
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 1
+B ctor. i = 32
+B ctor. i = 33
+A dtor. i = 0
+B dtor. i = 33
+B dtor. i = 32
+In main's catch
+B ctor. i = 34
+B ctor. i = 35
+A dtor. i = 25
+B dtor. i = 35
+B dtor. i = 34
+B ctor. i = 36
+B ctor. i = 37
+A dtor. i = 22
+B dtor. i = 37
+B dtor. i = 36
+
+
+Test #4
+A ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+A ctor. i = 3
+A ctor. i = 4
+A ctor. i = 5
+A ctor. i = 6
+B ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+Throwing
+B ctor. i = 13
+B ctor. i = 14
+A copy ctor. i = 15
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 16
+B ctor. i = 17
+A copy ctor. i = 18
+B dtor. i = 17
+B dtor. i = 16
+B ctor. i = 19
+B ctor. i = 20
+A dtor. i = 12
+B dtor. i = 20
+B dtor. i = 19
+B ctor. i = 21
+B ctor. i = 22
+A dtor. i = 9
+B dtor. i = 22
+B dtor. i = 21
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 8
+B dtor. i = 24
+B dtor. i = 23
+In catch;
+A ctor. i = 25
+Rethrowing
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 25
+B dtor. i = 27
+B dtor. i = 26
+B ctor. i = 28
+B ctor. i = 29
+A dtor. i = 18
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 30
+B ctor. i = 31
+A copy ctor. i = 32
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 7
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 6
+B dtor. i = 34
+B dtor. i = 33
+B ctor. i = 35
+B ctor. i = 36
+A dtor. i = 5
+B dtor. i = 36
+B dtor. i = 35
+In catch #1
+B ctor. i = 37
+Rethrowing
+B dtor. i = 37
+B ctor. i = 38
+B ctor. i = 39
+A dtor. i = 32
+B dtor. i = 39
+B dtor. i = 38
+B ctor. i = 40
+B ctor. i = 41
+A dtor. i = 4
+B dtor. i = 41
+B dtor. i = 40
+B ctor. i = 42
+B ctor. i = 43
+A dtor. i = 3
+B dtor. i = 43
+B dtor. i = 42
+In catch #2
+A ctor. i = 44
+Throwing new a
+B ctor. i = 45
+B ctor. i = 46
+A copy ctor. i = 47
+B dtor. i = 46
+B dtor. i = 45
+B ctor. i = 48
+B ctor. i = 49
+A copy ctor. i = 50
+B dtor. i = 49
+B dtor. i = 48
+B ctor. i = 51
+B ctor. i = 52
+A dtor. i = 44
+B dtor. i = 52
+B dtor. i = 51
+B ctor. i = 53
+B ctor. i = 54
+A dtor. i = 15
+B dtor. i = 54
+B dtor. i = 53
+B dtor. i = 2
+In catch #3
+B ctor. i = 55
+Rethrowing
+B dtor. i = 55
+B ctor. i = 56
+B ctor. i = 57
+A dtor. i = 50
+B dtor. i = 57
+B dtor. i = 56
+B ctor. i = 58
+B ctor. i = 59
+A copy ctor. i = 60
+B dtor. i = 59
+B dtor. i = 58
+B dtor. i = 1
+B ctor. i = 61
+B ctor. i = 62
+A dtor. i = 0
+B dtor. i = 62
+B dtor. i = 61
+In main's catch
+B ctor. i = 63
+B ctor. i = 64
+A dtor. i = 60
+B dtor. i = 64
+B dtor. i = 63
+B ctor. i = 65
+B ctor. i = 66
+A dtor. i = 47
+B dtor. i = 66
+B dtor. i = 65
+
+
+Test #5
+A ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A ctor. i = 5
+B ctor. i = 6
+B ctor. i = 7
+A copy ctor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+Throwing
+B ctor. i = 9
+B ctor. i = 10
+A copy ctor. i = 11
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 8
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 5
+B dtor. i = 18
+B dtor. i = 17
+B dtor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+A ctor. i = 19
+In catch #2
+B ctor. i = 20
+Throwing a new b
+B copy ctor. i = 21
+B copy ctor. i = 22
+B dtor. i = 20
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 19
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 25
+B ctor. i = 26
+A dtor. i = 14
+B dtor. i = 26
+B dtor. i = 25
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 11
+B dtor. i = 28
+B dtor. i = 27
+B dtor. i = 1
+In catch #3
+Throwing a new a
+A ctor. i = 29
+B ctor. i = 30
+B ctor. i = 31
+A copy ctor. i = 32
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 22
+B dtor. i = 21
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 0
+B dtor. i = 34
+B dtor. i = 33
+In main's catch
+B ctor. i = 35
+B ctor. i = 36
+A dtor. i = 32
+B dtor. i = 36
+B dtor. i = 35
+B ctor. i = 37
+B ctor. i = 38
+A dtor. i = 29
+B dtor. i = 38
+B dtor. i = 37
+
+
+Test #6
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+Throwing a b
+B copy ctor. i = 3
+B copy ctor. i = 4
+B dtor. i = 2
+B ctor. i = 5
+In catch #1
+Throwing a new b
+B copy ctor. i = 6
+B copy ctor. i = 7
+B dtor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+B dtor. i = 1
+B ctor. i = 8
+In catch #2
+Throwing a new b
+B copy ctor. i = 9
+B copy ctor. i = 10
+B dtor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+B dtor. i = 0
+A ctor. i = 11
+In catch #3
+Throwing a new a
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 15
+B ctor. i = 16
+A copy ctor. i = 17
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 11
+B dtor. i = 19
+B dtor. i = 18
+B dtor. i = 10
+B dtor. i = 9
+In main's catch
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 17
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 14
+B dtor. i = 23
+B dtor. i = 22
+
+
+Test #7
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+Throwing a b
+B ctor. i = 3
+B copy ctor. i = 4
+B dtor. i = 2
+B ctor. i = 5
+In catch #1
+B ctor. i = 6
+Rethrowing b
+B copy ctor. i = 7
+B dtor. i = 6
+B ctor. i = 8
+In catch #1 of catch#1
+Rethrowing b
+B dtor. i = 8
+B dtor. i = 7
+B copy ctor. i = 9
+B dtor. i = 5
+B dtor. i = 4
+B dtor. i = 1
+B ctor. i = 10
+In catch #2
+Throwing a new A
+A ctor. i = 11
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B dtor. i = 10
+B dtor. i = 9
+B dtor. i = 3
+B dtor. i = 0
+In main's catch
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 14
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 11
+B dtor. i = 18
+B dtor. i = 17
+
+
+Test #8
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+Throwing a b
+B ctor. i = 4
+B ctor. i = 5
+B copy ctor. i = 6
+B dtor. i = 4
+B dtor. i = 3
+B ctor. i = 7
+In catch #1
+B ctor. i = 8
+Rethrowing b
+A ctor. i = 9
+Rethrowing
+B copy ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+B dtor. i = 8
+B ctor. i = 13
+In catch #1 of catch#1
+Rethrowing b
+A ctor. i = 14
+Rethrowing
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 14
+B dtor. i = 16
+B dtor. i = 15
+B dtor. i = 13
+B dtor. i = 10
+B copy ctor. i = 17
+B dtor. i = 7
+B dtor. i = 6
+B dtor. i = 2
+B dtor. i = 1
+B ctor. i = 18
+In catch #2
+Throwing a new A
+A ctor. i = 19
+B ctor. i = 20
+B ctor. i = 21
+A copy ctor. i = 22
+B dtor. i = 21
+B dtor. i = 20
+B dtor. i = 18
+B dtor. i = 17
+B dtor. i = 5
+B dtor. i = 0
+In main's catch
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 22
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 25
+B ctor. i = 26
+A dtor. i = 19
+B dtor. i = 26
+B dtor. i = 25
+
+
+Test #9
+B ctor. i = 0
+Throwing B
+B copy ctor. i = 1
+B dtor. i = 0
+In catch #1
+Rethrow
+In catch #2
+B dtor. i = 1
+End of test9, throwing a A
+A ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A copy ctor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+In main's catch
+B ctor. i = 6
+B ctor. i = 7
+A dtor. i = 5
+B dtor. i = 7
+B dtor. i = 6
+B ctor. i = 8
+B ctor. i = 9
+A dtor. i = 2
+B dtor. i = 9
+B dtor. i = 8
+
+
+Test #10
+B ctor. i = 0
+Throwing B
+B copy ctor. i = 1
+B dtor. i = 0
+In catch #1
+Throwing a new B()
+B ctor. i = 2
+In catch #2
+B dtor. i = 2
+B dtor. i = 1
+End of test10, throwing a A
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+In main's catch
+B ctor. i = 7
+B ctor. i = 8
+A dtor. i = 6
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 9
+B ctor. i = 10
+A dtor. i = 3
+B dtor. i = 10
+B dtor. i = 9
+
+
+Passed
diff --git a/modules/rostests/apitests/compiler/ms/eh/ehthrow.arm
b/modules/rostests/apitests/compiler/ms/eh/ehthrow.arm
new file mode 100644
index 00000000000..9154c519367
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ehthrow.arm
@@ -0,0 +1,676 @@
+
+Test #1
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A copy ctor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+Throwing
+B ctor. i = 6
+B ctor. i = 7
+A copy ctor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+B ctor. i = 9
+B ctor. i = 10
+A copy ctor. i = 11
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 12
+B ctor. i = 13
+A dtor. i = 5
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 2
+B dtor. i = 15
+B dtor. i = 14
+B dtor. i = 1
+B ctor. i = 16
+B ctor. i = 17
+A dtor. i = 0
+B dtor. i = 17
+B dtor. i = 16
+In main's catch
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 11
+B dtor. i = 19
+B dtor. i = 18
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 8
+B dtor. i = 21
+B dtor. i = 20
+
+
+Test #2
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+Throwing
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 6
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 3
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 2
+B dtor. i = 18
+B dtor. i = 17
+In catch;
+A ctor. i = 19
+Rethrowing
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 19
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 12
+B dtor. i = 23
+B dtor. i = 22
+B ctor. i = 24
+B ctor. i = 25
+A copy ctor. i = 26
+B dtor. i = 25
+B dtor. i = 24
+B dtor. i = 1
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 0
+B dtor. i = 28
+B dtor. i = 27
+In main's catch
+B ctor. i = 29
+B ctor. i = 30
+A dtor. i = 26
+B dtor. i = 30
+B dtor. i = 29
+B ctor. i = 31
+B ctor. i = 32
+A dtor. i = 9
+B dtor. i = 32
+B dtor. i = 31
+
+
+Test #3
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+Throwing
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 6
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 3
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 2
+B dtor. i = 18
+B dtor. i = 17
+In catch
+A ctor. i = 19
+Throwing new a
+B ctor. i = 20
+B ctor. i = 21
+A copy ctor. i = 22
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 23
+B ctor. i = 24
+A copy ctor. i = 25
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 19
+B dtor. i = 27
+B dtor. i = 26
+B ctor. i = 28
+B ctor. i = 29
+A dtor. i = 12
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 30
+B ctor. i = 31
+A dtor. i = 9
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 1
+B ctor. i = 32
+B ctor. i = 33
+A dtor. i = 0
+B dtor. i = 33
+B dtor. i = 32
+In main's catch
+B ctor. i = 34
+B ctor. i = 35
+A dtor. i = 25
+B dtor. i = 35
+B dtor. i = 34
+B ctor. i = 36
+B ctor. i = 37
+A dtor. i = 22
+B dtor. i = 37
+B dtor. i = 36
+
+
+Test #4
+A ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+A ctor. i = 3
+A ctor. i = 4
+A ctor. i = 5
+A ctor. i = 6
+B ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+Throwing
+B ctor. i = 13
+B ctor. i = 14
+A copy ctor. i = 15
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 16
+B ctor. i = 17
+A copy ctor. i = 18
+B dtor. i = 17
+B dtor. i = 16
+B ctor. i = 19
+B ctor. i = 20
+A dtor. i = 12
+B dtor. i = 20
+B dtor. i = 19
+B ctor. i = 21
+B ctor. i = 22
+A dtor. i = 9
+B dtor. i = 22
+B dtor. i = 21
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 8
+B dtor. i = 24
+B dtor. i = 23
+In catch;
+A ctor. i = 25
+Rethrowing
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 25
+B dtor. i = 27
+B dtor. i = 26
+B ctor. i = 28
+B ctor. i = 29
+A dtor. i = 18
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 30
+B ctor. i = 31
+A copy ctor. i = 32
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 7
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 6
+B dtor. i = 34
+B dtor. i = 33
+B ctor. i = 35
+B ctor. i = 36
+A dtor. i = 5
+B dtor. i = 36
+B dtor. i = 35
+In catch #1
+B ctor. i = 37
+Rethrowing
+B dtor. i = 37
+B ctor. i = 38
+B ctor. i = 39
+A dtor. i = 32
+B dtor. i = 39
+B dtor. i = 38
+B ctor. i = 40
+B ctor. i = 41
+A dtor. i = 4
+B dtor. i = 41
+B dtor. i = 40
+B ctor. i = 42
+B ctor. i = 43
+A dtor. i = 3
+B dtor. i = 43
+B dtor. i = 42
+In catch #2
+A ctor. i = 44
+Throwing new a
+B ctor. i = 45
+B ctor. i = 46
+A copy ctor. i = 47
+B dtor. i = 46
+B dtor. i = 45
+B ctor. i = 48
+B ctor. i = 49
+A copy ctor. i = 50
+B dtor. i = 49
+B dtor. i = 48
+B ctor. i = 51
+B ctor. i = 52
+A dtor. i = 44
+B dtor. i = 52
+B dtor. i = 51
+B ctor. i = 53
+B ctor. i = 54
+A dtor. i = 15
+B dtor. i = 54
+B dtor. i = 53
+B dtor. i = 2
+In catch #3
+B ctor. i = 55
+Rethrowing
+B dtor. i = 55
+B ctor. i = 56
+B ctor. i = 57
+A dtor. i = 50
+B dtor. i = 57
+B dtor. i = 56
+B ctor. i = 58
+B ctor. i = 59
+A copy ctor. i = 60
+B dtor. i = 59
+B dtor. i = 58
+B dtor. i = 1
+B ctor. i = 61
+B ctor. i = 62
+A dtor. i = 0
+B dtor. i = 62
+B dtor. i = 61
+In main's catch
+B ctor. i = 63
+B ctor. i = 64
+A dtor. i = 60
+B dtor. i = 64
+B dtor. i = 63
+B ctor. i = 65
+B ctor. i = 66
+A dtor. i = 47
+B dtor. i = 66
+B dtor. i = 65
+
+
+Test #5
+A ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A ctor. i = 5
+B ctor. i = 6
+B ctor. i = 7
+A copy ctor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+Throwing
+B ctor. i = 9
+B ctor. i = 10
+A copy ctor. i = 11
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 8
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 5
+B dtor. i = 18
+B dtor. i = 17
+B dtor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+A ctor. i = 19
+In catch #2
+B ctor. i = 20
+Throwing a new b
+B copy ctor. i = 21
+B copy ctor. i = 22
+B dtor. i = 20
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 19
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 25
+B ctor. i = 26
+A dtor. i = 14
+B dtor. i = 26
+B dtor. i = 25
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 11
+B dtor. i = 28
+B dtor. i = 27
+B dtor. i = 1
+In catch #3
+Throwing a new a
+A ctor. i = 29
+B ctor. i = 30
+B ctor. i = 31
+A copy ctor. i = 32
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 22
+B dtor. i = 21
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 0
+B dtor. i = 34
+B dtor. i = 33
+In main's catch
+B ctor. i = 35
+B ctor. i = 36
+A dtor. i = 32
+B dtor. i = 36
+B dtor. i = 35
+B ctor. i = 37
+B ctor. i = 38
+A dtor. i = 29
+B dtor. i = 38
+B dtor. i = 37
+
+
+Test #6
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+Throwing a b
+B copy ctor. i = 3
+B copy ctor. i = 4
+B dtor. i = 2
+B ctor. i = 5
+In catch #1
+Throwing a new b
+B copy ctor. i = 6
+B copy ctor. i = 7
+B dtor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+B dtor. i = 1
+B ctor. i = 8
+In catch #2
+Throwing a new b
+B copy ctor. i = 9
+B copy ctor. i = 10
+B dtor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+B dtor. i = 0
+A ctor. i = 11
+In catch #3
+Throwing a new a
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 15
+B ctor. i = 16
+A copy ctor. i = 17
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 11
+B dtor. i = 19
+B dtor. i = 18
+B dtor. i = 10
+B dtor. i = 9
+In main's catch
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 17
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 14
+B dtor. i = 23
+B dtor. i = 22
+
+
+Test #7
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+Throwing a b
+B ctor. i = 3
+B copy ctor. i = 4
+B dtor. i = 2
+B ctor. i = 5
+In catch #1
+B ctor. i = 6
+Rethrowing b
+B copy ctor. i = 7
+B dtor. i = 6
+B ctor. i = 8
+In catch #1 of catch#1
+Rethrowing b
+B dtor. i = 8
+B dtor. i = 7
+B dtor. i = 5
+B dtor. i = 4
+B copy ctor. i = 9
+B dtor. i = 1
+B ctor. i = 10
+In catch #2
+Throwing a new A
+A ctor. i = 11
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B dtor. i = 10
+B dtor. i = 9
+B dtor. i = 3
+B dtor. i = 0
+In main's catch
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 14
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 11
+B dtor. i = 18
+B dtor. i = 17
+
+
+Test #8
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+Throwing a b
+B ctor. i = 4
+B ctor. i = 5
+B copy ctor. i = 6
+B dtor. i = 4
+B dtor. i = 3
+B ctor. i = 7
+In catch #1
+B ctor. i = 8
+Rethrowing b
+A ctor. i = 9
+Rethrowing
+B copy ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+B dtor. i = 8
+B ctor. i = 13
+In catch #1 of catch#1
+Rethrowing b
+A ctor. i = 14
+Rethrowing
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 14
+B dtor. i = 16
+B dtor. i = 15
+B dtor. i = 13
+B dtor. i = 10
+B copy ctor. i = 17
+B dtor. i = 7
+B dtor. i = 6
+B dtor. i = 2
+B dtor. i = 1
+B ctor. i = 18
+In catch #2
+Throwing a new A
+A ctor. i = 19
+B ctor. i = 20
+B ctor. i = 21
+A copy ctor. i = 22
+B dtor. i = 21
+B dtor. i = 20
+B dtor. i = 18
+B dtor. i = 17
+B dtor. i = 5
+B dtor. i = 0
+In main's catch
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 22
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 25
+B ctor. i = 26
+A dtor. i = 19
+B dtor. i = 26
+B dtor. i = 25
+
+
+Test #9
+B ctor. i = 0
+Throwing B
+B copy ctor. i = 1
+B dtor. i = 0
+In catch #1
+Rethrow
+In catch #2
+B dtor. i = 1
+End of test9, throwing a A
+A ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A copy ctor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+In main's catch
+B ctor. i = 6
+B ctor. i = 7
+A dtor. i = 5
+B dtor. i = 7
+B dtor. i = 6
+B ctor. i = 8
+B ctor. i = 9
+A dtor. i = 2
+B dtor. i = 9
+B dtor. i = 8
+
+
+Test #10
+B ctor. i = 0
+Throwing B
+B copy ctor. i = 1
+B dtor. i = 0
+In catch #1
+Throwing a new B()
+B ctor. i = 2
+In catch #2
+B dtor. i = 2
+B dtor. i = 1
+End of test10, throwing a A
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+In main's catch
+B ctor. i = 7
+B ctor. i = 8
+A dtor. i = 6
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 9
+B ctor. i = 10
+A dtor. i = 3
+B dtor. i = 10
+B dtor. i = 9
+
+
+Passed
diff --git a/modules/rostests/apitests/compiler/ms/eh/ehthrow.cxx
b/modules/rostests/apitests/compiler/ms/eh/ehthrow.cxx
new file mode 100644
index 00000000000..27a695638f2
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ehthrow.cxx
@@ -0,0 +1,547 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for
+// full license information.
+
+/*
+ Tests some throw and rethrow situations (mostly CRT a test)
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+#define FALSE 0
+#define TRUE 1
+#define NO_CTOR_THROW 1
+#define NO_DTOR_THROW 2
+
+
+int Object[100];
+int CurrentObjectNumber, Test;
+int MaxTest = 10;
+int MaxObjectCount = 1;
+int Fail;
+
+
+void FAIL(int i)
+{
+ printf("FAILED on %d\n", i);
+ Fail++;
+}
+
+void dealloc(int i, int no_throw)
+{
+ /* Make sure i is valid, and object exists */
+ if(i<0 || i>=MaxObjectCount || !Object[i])
+ FAIL(i);
+
+ Object[i] = 0;
+}
+
+void alloc(int i, int no_throw)
+{
+ if(CurrentObjectNumber > MaxObjectCount)
+ MaxObjectCount = CurrentObjectNumber;
+
+ /* Object already exists? */
+ if(Object[i]) FAIL(i);
+
+ Object[i] = 1;
+}
+
+class B
+{
+public:
+ int i;
+ int flag;
+ B();
+ B(int);
+ B(const B &b);
+ ~B();
+};
+
+B::B()
+{
+ i = CurrentObjectNumber++;
+ printf("B ctor. i = %d\n", i);
+ alloc(i, FALSE);
+}
+
+B::B(int f)
+{
+ i = CurrentObjectNumber++;
+ flag = f;
+ printf("B ctor. i = %d\n", i);
+ alloc(i, flag==NO_CTOR_THROW);
+}
+
+B::B(const B &b)
+{
+ i = CurrentObjectNumber++;
+ printf("B copy ctor. i = %d\n", i);
+ alloc(i, FALSE);
+}
+
+B::~B()
+{
+ printf("B dtor. i = %d\n", i);
+ dealloc(i, flag==NO_DTOR_THROW);
+}
+
+class A
+{
+public:
+ int i;
+ A();
+ A(int)
+ {
+ i = CurrentObjectNumber++;
+ printf("A(int) ctor. i = %d\n", i);
+ alloc(i, FALSE);
+ }
+ A operator+(A a);
+ A(const A &a)
+ {
+ /* Try objects in ctor */
+ B b1 = NO_DTOR_THROW, b2 = NO_DTOR_THROW;
+
+ i = CurrentObjectNumber++;
+ printf("A copy ctor. i = %d\n", i);
+ alloc(i, FALSE);
+ }
+
+ ~A(){
+ /* Try objects in dtor */
+ B b1 = NO_CTOR_THROW, b2 = NO_CTOR_THROW;
+
+ printf("A dtor. i = %d\n", i);
+ dealloc(i, FALSE);
+ };
+};
+
+A::A()
+{
+ i=CurrentObjectNumber++;
+ printf("A ctor. i = %d\n", i);
+ alloc(i, FALSE);
+}
+
+A A::operator+(A a)
+{
+ printf("A%d + A%d\n", i, a.i);
+ return A();
+}
+
+void Throwa(A a)
+{
+ printf("Throwing\n");
+ throw a;
+}
+
+void bar()
+{
+ A a;
+
+ Throwa(a);
+}
+
+void foobar()
+{
+ B b;
+ bar();
+}
+
+// Somehow, inlining this causes different unwinding order..
+
+__declspec(noinline) void Rethrow2()
+{
+ A a;
+ printf("Rethrowing\n");
+ throw;
+}
+
+#pragma inline_depth(0)
+void Rethrow()
+{
+ Rethrow2();
+}
+#pragma inline_depth()
+
+void foobar2()
+{
+ B b;
+
+ try{
+ A a;
+ bar();
+ }catch(A a){
+ printf("In catch;\n");
+ Rethrow();
+ }
+}
+
+void foobar3()
+{
+ B b;
+
+ try{
+ A a;
+ bar();
+ }catch(A a){
+ printf("In catch\n");
+ A a2;
+
+ printf("Throwing new a\n");
+ throw a2;
+ }
+}
+
+void foobar4()
+{
+ B b;
+
+ try{
+ B b;
+ try{
+ A a1, a2;
+ try {
+ A a1, a2;
+ foobar2();
+ }catch(A a){
+ printf("In catch #1\n");
+ B b;
+ printf("Rethrowing\n");
+ throw;
+ }
+ }catch(A &a){
+ printf("In catch #2\n");
+ A a2;
+
+ printf("Throwing new a\n");
+ throw a;
+ }
+ }catch(A a){
+ printf("In catch #3\n");
+ B b;
+ printf("Rethrowing\n");
+ throw;
+ }
+}
+
+__declspec(noinline) void throw_B_2()
+{
+ B b;
+ printf("Throwing a new b\n");
+ throw b;
+}
+
+#pragma inline_depth(0)
+void throw_B()
+{
+ throw_B_2();
+}
+#pragma inline_depth()
+
+
+void foobar5()
+{
+ try {
+ B b1;
+ try {
+ B b2;
+ try {
+ B b3;
+ foobar();
+ }catch(B b){
+ printf("In catch #1\n");
+ FAIL(-1);
+ }
+ FAIL(-1);
+ }catch(A a){
+ A a2;
+ printf("In catch #2\n");
+ throw_B();
+ }
+ FAIL(-1);
+ }catch(B b){
+ printf("In catch #3\n");
+ printf("Throwing a new a\n");
+ throw A();
+ }
+ FAIL(-1);
+}
+
+
+/* Simple throw with unwinds */
+void test1()
+{
+ A a;
+ foobar();
+}
+
+/* Throw followed by a rethrow */
+void test2()
+{
+ A a;
+ foobar2();
+}
+
+/* Throw followed by a new throw */
+void test3()
+{
+ A a;
+ foobar3();
+}
+
+/* Nested trys with rethrow/throw/rethrow */
+void test4()
+{
+ A a;
+ foobar4();
+}
+
+/* Makes sure a new throw skips appropriate unwound frames. */
+void test5()
+{
+ A a;
+ foobar5();
+}
+
+// Tests 3 level of new throw
+void test6()
+{
+ try{
+ B b1;
+ try{
+ B b2;
+ try{
+ B b3;
+ printf("Throwing a b\n");
+ throw(b3);
+ }catch(B b){
+ B b4;
+ printf("In catch #1\n");
+ printf("Throwing a new b\n");
+ throw(b4);
+ }
+ FAIL(-1);
+ }catch(B b){
+ B b5;
+ printf("In catch #2\n");
+ printf("Throwing a new b\n");
+ throw(b5);
+ }
+ FAIL(-1);
+ }catch(B b){
+ A a1;
+ printf("In catch #3\n");
+ printf("Throwing a new a\n");
+ throw(a1);
+ }
+ FAIL(-1);
+}
+
+// Testing try/catch inside a catch
+void test7()
+{
+ B b1;
+ try{
+ B b2;
+ try{
+ B b3;
+
+ printf("Throwing a b\n");
+ throw(B());
+ }catch(B b){
+ B b4;
+ printf("In catch #1\n");
+ try{
+ B b5;
+ printf("Rethrowing b\n");
+ throw;
+ }catch(B b){
+ B b5;
+ printf("In catch #1 of catch#1\n");
+ printf("Rethrowing b\n");
+ throw;
+ }
+ }
+ }catch(B b){
+ B b6;
+ printf("In catch #2\n");
+ printf("Throwing a new A\n");
+ throw(A());
+ }
+}
+
+void ThrowB()
+{
+ B b;
+
+ throw(B());
+}
+
+void bar8()
+{
+ try{
+ B b5;
+ printf("Rethrowing b\n");
+ Rethrow();
+ }catch(B b){
+ B b5;
+ printf("In catch #1 of catch#1\n");
+ printf("Rethrowing b\n");
+ Rethrow();
+ }
+}
+
+void foo8()
+{
+ B b;
+ try{
+ B b3;
+
+ printf("Throwing a b\n");
+ ThrowB();
+ }catch(B b){
+ B b4;
+ printf("In catch #1\n");
+ bar8();
+ }
+}
+
+// Testing call to try/catch function inside a catch
+void test8()
+{
+ B b1;
+ try{
+ B b2;
+ foo8();
+ }catch(B b){
+ B b6;
+ printf("In catch #2\n");
+ printf("Throwing a new A\n");
+ throw(A());
+ }
+}
+
+void foo9()
+{
+ try {
+ puts("Rethrow");
+ throw;
+ }catch(...){
+ puts("In catch #2");
+ }
+}
+
+void test9()
+{
+ try{
+ B b;
+ puts("Throwing B");
+ throw b;
+ }catch(...){
+ puts("In catch #1");
+ foo9();
+ }
+ puts("End of test9, throwing a A");
+ throw A();
+}
+
+void foo10()
+{
+ try {
+ puts("Throwing a new B()");
+ throw B();
+ }catch(...){
+ puts("In catch #2");
+ }
+}
+
+void test10()
+{
+ try{
+ B b;
+ puts("Throwing B");
+ throw b;
+ }catch(...){
+ puts("In catch #1");
+ foo10();
+ }
+ puts("End of test10, throwing a A");
+ throw A();
+}
+
+int main()
+{
+ int i;
+
+ /* Call test(), with a different ctor/dtor throwing each time */
+ for(Test = 1; Test <= MaxTest; Test++) {
+
+ CurrentObjectNumber = 0;
+
+ printf("\nTest #%d\n", Test);
+
+ try {
+ switch(Test){
+ case 1:
+ test1();
+ break;
+ case 2:
+ test2();
+ break;
+ case 3:
+ test3();
+ break;
+ case 4:
+ test4();
+ break;
+ case 5:
+ test5();
+ break;
+ case 6:
+ test6();
+ break;
+ case 7:
+ test7();
+ break;
+ case 8:
+ test8();
+ break;
+ case 9:
+ test9();
+ break;
+ case 10:
+ test10();
+ break;
+ }
+
+ FAIL(-1);
+
+ }catch(A a){
+ printf("In main's catch\n");
+ }catch(...){
+ FAIL(-1);
+ }
+
+ /* Any objects which didn't get dtor'd? */
+ for(i = 0; i < MaxObjectCount; i++) {
+ if(Object[i]) {
+ FAIL(i);
+ Object[i] = 0;
+ }
+ }
+
+ printf("\n");
+ }
+
+ printf("\n");
+ if(Fail)
+ printf("FAILED %d tests\n", Fail);
+ else
+ printf("Passed\n");
+
+}
diff --git a/modules/rostests/apitests/compiler/ms/eh/ehthrow.out
b/modules/rostests/apitests/compiler/ms/eh/ehthrow.out
new file mode 100644
index 00000000000..7f2237199d8
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ehthrow.out
@@ -0,0 +1,676 @@
+
+Test #1
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A copy ctor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+Throwing
+B ctor. i = 6
+B ctor. i = 7
+A copy ctor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+B ctor. i = 9
+B ctor. i = 10
+A copy ctor. i = 11
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 12
+B ctor. i = 13
+A dtor. i = 5
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 2
+B dtor. i = 15
+B dtor. i = 14
+B dtor. i = 1
+B ctor. i = 16
+B ctor. i = 17
+A dtor. i = 0
+B dtor. i = 17
+B dtor. i = 16
+In main's catch
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 11
+B dtor. i = 19
+B dtor. i = 18
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 8
+B dtor. i = 21
+B dtor. i = 20
+
+
+Test #2
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+Throwing
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 6
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 3
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 2
+B dtor. i = 18
+B dtor. i = 17
+In catch;
+A ctor. i = 19
+Rethrowing
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 19
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 12
+B dtor. i = 23
+B dtor. i = 22
+B ctor. i = 24
+B ctor. i = 25
+A copy ctor. i = 26
+B dtor. i = 25
+B dtor. i = 24
+B dtor. i = 1
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 0
+B dtor. i = 28
+B dtor. i = 27
+In main's catch
+B ctor. i = 29
+B ctor. i = 30
+A dtor. i = 26
+B dtor. i = 30
+B dtor. i = 29
+B ctor. i = 31
+B ctor. i = 32
+A dtor. i = 9
+B dtor. i = 32
+B dtor. i = 31
+
+
+Test #3
+A ctor. i = 0
+B ctor. i = 1
+A ctor. i = 2
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+Throwing
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 6
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 3
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 2
+B dtor. i = 18
+B dtor. i = 17
+In catch
+A ctor. i = 19
+Throwing new a
+B ctor. i = 20
+B ctor. i = 21
+A copy ctor. i = 22
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 23
+B ctor. i = 24
+A copy ctor. i = 25
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 9
+B dtor. i = 27
+B dtor. i = 26
+B ctor. i = 28
+B ctor. i = 29
+A dtor. i = 19
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 30
+B ctor. i = 31
+A dtor. i = 12
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 1
+B ctor. i = 32
+B ctor. i = 33
+A dtor. i = 0
+B dtor. i = 33
+B dtor. i = 32
+In main's catch
+B ctor. i = 34
+B ctor. i = 35
+A dtor. i = 25
+B dtor. i = 35
+B dtor. i = 34
+B ctor. i = 36
+B ctor. i = 37
+A dtor. i = 22
+B dtor. i = 37
+B dtor. i = 36
+
+
+Test #4
+A ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+A ctor. i = 3
+A ctor. i = 4
+A ctor. i = 5
+A ctor. i = 6
+B ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+B ctor. i = 10
+B ctor. i = 11
+A copy ctor. i = 12
+B dtor. i = 11
+B dtor. i = 10
+Throwing
+B ctor. i = 13
+B ctor. i = 14
+A copy ctor. i = 15
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 16
+B ctor. i = 17
+A copy ctor. i = 18
+B dtor. i = 17
+B dtor. i = 16
+B ctor. i = 19
+B ctor. i = 20
+A dtor. i = 12
+B dtor. i = 20
+B dtor. i = 19
+B ctor. i = 21
+B ctor. i = 22
+A dtor. i = 9
+B dtor. i = 22
+B dtor. i = 21
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 8
+B dtor. i = 24
+B dtor. i = 23
+In catch;
+A ctor. i = 25
+Rethrowing
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 25
+B dtor. i = 27
+B dtor. i = 26
+B ctor. i = 28
+B ctor. i = 29
+A dtor. i = 18
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 30
+B ctor. i = 31
+A copy ctor. i = 32
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 7
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 6
+B dtor. i = 34
+B dtor. i = 33
+B ctor. i = 35
+B ctor. i = 36
+A dtor. i = 5
+B dtor. i = 36
+B dtor. i = 35
+In catch #1
+B ctor. i = 37
+Rethrowing
+B dtor. i = 37
+B ctor. i = 38
+B ctor. i = 39
+A dtor. i = 32
+B dtor. i = 39
+B dtor. i = 38
+B ctor. i = 40
+B ctor. i = 41
+A dtor. i = 4
+B dtor. i = 41
+B dtor. i = 40
+B ctor. i = 42
+B ctor. i = 43
+A dtor. i = 3
+B dtor. i = 43
+B dtor. i = 42
+In catch #2
+A ctor. i = 44
+Throwing new a
+B ctor. i = 45
+B ctor. i = 46
+A copy ctor. i = 47
+B dtor. i = 46
+B dtor. i = 45
+B ctor. i = 48
+B ctor. i = 49
+A copy ctor. i = 50
+B dtor. i = 49
+B dtor. i = 48
+B ctor. i = 51
+B ctor. i = 52
+A dtor. i = 15
+B dtor. i = 52
+B dtor. i = 51
+B ctor. i = 53
+B ctor. i = 54
+A dtor. i = 44
+B dtor. i = 54
+B dtor. i = 53
+B dtor. i = 2
+In catch #3
+B ctor. i = 55
+Rethrowing
+B dtor. i = 55
+B ctor. i = 56
+B ctor. i = 57
+A dtor. i = 50
+B dtor. i = 57
+B dtor. i = 56
+B ctor. i = 58
+B ctor. i = 59
+A copy ctor. i = 60
+B dtor. i = 59
+B dtor. i = 58
+B dtor. i = 1
+B ctor. i = 61
+B ctor. i = 62
+A dtor. i = 0
+B dtor. i = 62
+B dtor. i = 61
+In main's catch
+B ctor. i = 63
+B ctor. i = 64
+A dtor. i = 60
+B dtor. i = 64
+B dtor. i = 63
+B ctor. i = 65
+B ctor. i = 66
+A dtor. i = 47
+B dtor. i = 66
+B dtor. i = 65
+
+
+Test #5
+A ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A ctor. i = 5
+B ctor. i = 6
+B ctor. i = 7
+A copy ctor. i = 8
+B dtor. i = 7
+B dtor. i = 6
+Throwing
+B ctor. i = 9
+B ctor. i = 10
+A copy ctor. i = 11
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 8
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 5
+B dtor. i = 18
+B dtor. i = 17
+B dtor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+A ctor. i = 19
+In catch #2
+B ctor. i = 20
+Throwing a new b
+B copy ctor. i = 21
+B copy ctor. i = 22
+B dtor. i = 20
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 11
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 25
+B ctor. i = 26
+A dtor. i = 19
+B dtor. i = 26
+B dtor. i = 25
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 14
+B dtor. i = 28
+B dtor. i = 27
+B dtor. i = 1
+In catch #3
+Throwing a new a
+A ctor. i = 29
+B ctor. i = 30
+B ctor. i = 31
+A copy ctor. i = 32
+B dtor. i = 31
+B dtor. i = 30
+B dtor. i = 21
+B dtor. i = 22
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 0
+B dtor. i = 34
+B dtor. i = 33
+In main's catch
+B ctor. i = 35
+B ctor. i = 36
+A dtor. i = 32
+B dtor. i = 36
+B dtor. i = 35
+B ctor. i = 37
+B ctor. i = 38
+A dtor. i = 29
+B dtor. i = 38
+B dtor. i = 37
+
+
+Test #6
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+Throwing a b
+B copy ctor. i = 3
+B copy ctor. i = 4
+B dtor. i = 2
+B ctor. i = 5
+In catch #1
+Throwing a new b
+B copy ctor. i = 6
+B copy ctor. i = 7
+B dtor. i = 3
+B dtor. i = 5
+B dtor. i = 4
+B dtor. i = 1
+B ctor. i = 8
+In catch #2
+Throwing a new b
+B copy ctor. i = 9
+B copy ctor. i = 10
+B dtor. i = 6
+B dtor. i = 8
+B dtor. i = 7
+B dtor. i = 0
+A ctor. i = 11
+In catch #3
+Throwing a new a
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 15
+B ctor. i = 16
+A copy ctor. i = 17
+B dtor. i = 16
+B dtor. i = 15
+B dtor. i = 9
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 11
+B dtor. i = 19
+B dtor. i = 18
+B dtor. i = 10
+In main's catch
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 17
+B dtor. i = 21
+B dtor. i = 20
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 14
+B dtor. i = 23
+B dtor. i = 22
+
+
+Test #7
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+Throwing a b
+B ctor. i = 3
+B copy ctor. i = 4
+B dtor. i = 2
+B ctor. i = 5
+In catch #1
+B ctor. i = 6
+Rethrowing b
+B copy ctor. i = 7
+B dtor. i = 6
+B ctor. i = 8
+In catch #1 of catch#1
+Rethrowing b
+B dtor. i = 8
+B dtor. i = 7
+B dtor. i = 5
+B dtor. i = 4
+B copy ctor. i = 9
+B dtor. i = 1
+B ctor. i = 10
+In catch #2
+Throwing a new A
+A ctor. i = 11
+B ctor. i = 12
+B ctor. i = 13
+A copy ctor. i = 14
+B dtor. i = 13
+B dtor. i = 12
+B dtor. i = 3
+B dtor. i = 10
+B dtor. i = 9
+B dtor. i = 0
+In main's catch
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 14
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 11
+B dtor. i = 18
+B dtor. i = 17
+
+
+Test #8
+B ctor. i = 0
+B ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+Throwing a b
+B ctor. i = 4
+B ctor. i = 5
+B copy ctor. i = 6
+B dtor. i = 4
+B dtor. i = 3
+B ctor. i = 7
+In catch #1
+B ctor. i = 8
+Rethrowing b
+A ctor. i = 9
+Rethrowing
+B copy ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+B dtor. i = 8
+B ctor. i = 13
+In catch #1 of catch#1
+Rethrowing b
+A ctor. i = 14
+Rethrowing
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 14
+B dtor. i = 16
+B dtor. i = 15
+B dtor. i = 13
+B dtor. i = 10
+B dtor. i = 7
+B dtor. i = 6
+B copy ctor. i = 17
+B dtor. i = 2
+B dtor. i = 1
+B ctor. i = 18
+In catch #2
+Throwing a new A
+A ctor. i = 19
+B ctor. i = 20
+B ctor. i = 21
+A copy ctor. i = 22
+B dtor. i = 21
+B dtor. i = 20
+B dtor. i = 5
+B dtor. i = 18
+B dtor. i = 17
+B dtor. i = 0
+In main's catch
+B ctor. i = 23
+B ctor. i = 24
+A dtor. i = 22
+B dtor. i = 24
+B dtor. i = 23
+B ctor. i = 25
+B ctor. i = 26
+A dtor. i = 19
+B dtor. i = 26
+B dtor. i = 25
+
+
+Test #9
+B ctor. i = 0
+Throwing B
+B copy ctor. i = 1
+B dtor. i = 0
+In catch #1
+Rethrow
+In catch #2
+B dtor. i = 1
+End of test9, throwing a A
+A ctor. i = 2
+B ctor. i = 3
+B ctor. i = 4
+A copy ctor. i = 5
+B dtor. i = 4
+B dtor. i = 3
+In main's catch
+B ctor. i = 6
+B ctor. i = 7
+A dtor. i = 5
+B dtor. i = 7
+B dtor. i = 6
+B ctor. i = 8
+B ctor. i = 9
+A dtor. i = 2
+B dtor. i = 9
+B dtor. i = 8
+
+
+Test #10
+B ctor. i = 0
+Throwing B
+B copy ctor. i = 1
+B dtor. i = 0
+In catch #1
+Throwing a new B()
+B ctor. i = 2
+In catch #2
+B dtor. i = 2
+B dtor. i = 1
+End of test10, throwing a A
+A ctor. i = 3
+B ctor. i = 4
+B ctor. i = 5
+A copy ctor. i = 6
+B dtor. i = 5
+B dtor. i = 4
+In main's catch
+B ctor. i = 7
+B ctor. i = 8
+A dtor. i = 6
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 9
+B ctor. i = 10
+A dtor. i = 3
+B dtor. i = 10
+B dtor. i = 9
+
+
+Passed
diff --git a/modules/rostests/apitests/compiler/ms/eh/ihateeh.cxx
b/modules/rostests/apitests/compiler/ms/eh/ihateeh.cxx
new file mode 100644
index 00000000000..960e74598c8
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ihateeh.cxx
@@ -0,0 +1,199 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for
+// full license information.
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define FALSE 0
+#define TRUE 1
+#define NO_CTOR_THROW 1
+#define NO_DTOR_THROW 2
+
+#define TEST_DTOR
+
+#define MAX_OBJECTS 500
+
+#define NOEXCEPT(_x)
+
+int Object[MAX_OBJECTS];
+int CurrentObjectNumber, ThrowCount, MaxObjectCount = 1;
+int Fail;
+
+void FAIL(int i) {
+ printf("FAILED on %d\n", i);
+ Fail++;
+}
+
+void dealloc(int i, int no_throw) {
+ /* Make sure i is valid, and object exists */
+ if (i < 0 || i >= MaxObjectCount || !Object[i])
+ FAIL(i);
+
+ Object[i] = 0;
+
+/* Try throw in this dtor.. */
+#ifdef TEST_DTOR
+ if (i + MaxObjectCount == ThrowCount && !no_throw) {
+ printf("Throwing\n");
+ throw(1);
+ }
+#endif
+}
+
+void alloc(int i, int no_throw) {
+ if (CurrentObjectNumber > MaxObjectCount)
+ MaxObjectCount = CurrentObjectNumber;
+
+ /* Object already exists? */
+ if (Object[i])
+ FAIL(i);
+
+ /* Try throw in this ctor.. */
+ if (i == ThrowCount && !no_throw) {
+ printf("Throwing\n");
+ throw(1);
+ }
+
+ if (i >= MAX_OBJECTS) {
+ printf("\n*** Number of objects exceeded. Increase MAX_OBJECTS ***\n\n");
+ FAIL(i);
+ i = 0;
+ }
+
+ Object[i] = 1;
+}
+
+class B {
+public:
+ int i;
+ int flag;
+ B();
+ B(int);
+ ~B() NOEXCEPT(false);
+};
+
+B::B() {
+ i = CurrentObjectNumber++;
+ printf("B ctor. i = %d\n", i);
+ alloc(i, FALSE);
+}
+
+B::B(int f) {
+ i = CurrentObjectNumber++;
+ flag = f;
+ printf("B ctor. i = %d\n", i);
+ alloc(i, flag == NO_CTOR_THROW);
+}
+
+B::~B() NOEXCEPT(false) {
+ printf("B dtor. i = %d\n", i);
+ dealloc(i, flag == NO_DTOR_THROW);
+}
+
+class A {
+public:
+ int i;
+ A();
+ A(int) {
+ i = CurrentObjectNumber++;
+ printf("A(int) ctor. i = %d\n", i);
+ alloc(i, FALSE);
+ }
+ A operator+(A a);
+ A(const A &a) {
+ /* Try objects in ctor */
+ B b1 = NO_DTOR_THROW, b2 = NO_DTOR_THROW;
+
+ i = CurrentObjectNumber++;
+ printf("A copy ctor. i = %d\n", i);
+ alloc(i, FALSE);
+ }
+
+ ~A() NOEXCEPT(false) {
+ /* Try objects in dtor */
+ B b1 = NO_CTOR_THROW, b2 = NO_CTOR_THROW;
+
+ printf("A dtor. i = %d\n", i);
+ dealloc(i, FALSE);
+ };
+};
+
+A::A() {
+ i = CurrentObjectNumber++;
+ printf("A ctor. i = %d\n", i);
+ alloc(i, FALSE);
+}
+
+A A::operator+(A a) {
+ printf("A%d + A%d\n", i, a.i);
+ return A();
+}
+
+A foo(A a1, A a2) { return a1 + a2; };
+
+int bar() {
+ A a;
+
+ return 666;
+}
+
+void foo2(int i, A a1, A a2, A a3) {
+ if (i != 666)
+ FAIL(666);
+ foo(a1, a3);
+}
+
+A test() {
+ puts("Try simple ctor");
+ A a1;
+
+ puts("Try question op ctor");
+ A a2 = (ThrowCount & 1) ? A() : ThrowCount;
+
+ puts("Try a more complex question op ctor");
+ A a3 = (ThrowCount & 1) ? A() + a1 + A() + a2 : a2 + A() + A() + ThrowCount;
+
+ puts("Try mbarg copy ctors, and return UDT");
+ A a4 = foo(a1, a2);
+
+ puts("Try a more complex mbarg copy ctors, and a function call");
+ foo2(bar(), a1 + a2, a2 + A() + a3 + a4, a3);
+
+ puts("Try temporary expressions, and return UDT");
+ return a1 + A() + a2 + A() + a3 + a4;
+}
+
+int main() {
+ int i;
+
+ /* Call test(), with a different ctor/dtor throwing each time */
+ for (ThrowCount = 0; ThrowCount < MaxObjectCount * 2; ThrowCount++) {
+ printf("ThrowCount = %d MaxObjectCount = %d\n", ThrowCount,
+ MaxObjectCount);
+
+ CurrentObjectNumber = 0;
+
+ try {
+ test();
+ } catch (int) {
+ printf("In catch\n");
+ }
+
+ /* Any objects which didn't get dtor'd? */
+ for (i = 0; i < MaxObjectCount; i++) {
+ if (Object[i]) {
+ FAIL(i);
+ Object[i] = 0;
+ }
+ }
+
+ printf("\n");
+ }
+
+ printf("\n");
+ if (Fail)
+ printf("FAILED %d tests\n", Fail);
+ else
+ printf("Passed\n");
+}
diff --git a/modules/rostests/apitests/compiler/ms/eh/ihateeh.out.correct
b/modules/rostests/apitests/compiler/ms/eh/ihateeh.out.correct
new file mode 100644
index 00000000000..48ca04381ce
--- /dev/null
+++ b/modules/rostests/apitests/compiler/ms/eh/ihateeh.out.correct
@@ -0,0 +1,73231 @@
+ThrowCount = 0 MaxObjectCount = 1
+Try simple ctor
+A ctor. i = 0
+Throwing
+In catch
+
+ThrowCount = 1 MaxObjectCount = 1
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+Throwing
+B ctor. i = 2
+B ctor. i = 3
+A dtor. i = 0
+B dtor. i = 3
+B dtor. i = 2
+In catch
+
+ThrowCount = 2 MaxObjectCount = 4
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+Throwing
+B ctor. i = 3
+B ctor. i = 4
+A dtor. i = 1
+B dtor. i = 4
+B dtor. i = 3
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 0
+B dtor. i = 6
+B dtor. i = 5
+In catch
+
+ThrowCount = 3 MaxObjectCount = 7
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+Throwing
+B dtor. i = 2
+B ctor. i = 4
+B ctor. i = 5
+A dtor. i = 1
+B dtor. i = 5
+B dtor. i = 4
+B ctor. i = 6
+B ctor. i = 7
+A dtor. i = 0
+B dtor. i = 7
+B dtor. i = 6
+In catch
+
+ThrowCount = 4 MaxObjectCount = 8
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+Throwing
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+B ctor. i = 7
+B ctor. i = 8
+A dtor. i = 0
+B dtor. i = 8
+B dtor. i = 7
+In catch
+
+ThrowCount = 5 MaxObjectCount = 9
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+A ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A copy ctor. i = 13
+B dtor. i = 12
+B dtor. i = 11
+A ctor. i = 14
+A14 + A13
+A ctor. i = 15
+B ctor. i = 16
+B ctor. i = 17
+A dtor. i = 13
+B dtor. i = 17
+B dtor. i = 16
+A15 + A10
+A ctor. i = 18
+B ctor. i = 19
+B ctor. i = 20
+A dtor. i = 10
+B dtor. i = 20
+B dtor. i = 19
+A18 + A9
+A ctor. i = 21
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 9
+B dtor. i = 23
+B dtor. i = 22
+B ctor. i = 24
+B ctor. i = 25
+A copy ctor. i = 26
+B dtor. i = 25
+B dtor. i = 24
+B ctor. i = 27
+B ctor. i = 28
+A dtor. i = 21
+B dtor. i = 28
+B dtor. i = 27
+B ctor. i = 29
+B ctor. i = 30
+A dtor. i = 18
+B dtor. i = 30
+B dtor. i = 29
+B ctor. i = 31
+B ctor. i = 32
+A dtor. i = 15
+B dtor. i = 32
+B dtor. i = 31
+B ctor. i = 33
+B ctor. i = 34
+A dtor. i = 14
+B dtor. i = 34
+B dtor. i = 33
+Try mbarg copy ctors, and return UDT
+B ctor. i = 35
+B ctor. i = 36
+A copy ctor. i = 37
+B dtor. i = 36
+B dtor. i = 35
+B ctor. i = 38
+B ctor. i = 39
+A copy ctor. i = 40
+B dtor. i = 39
+B dtor. i = 38
+B ctor. i = 41
+B ctor. i = 42
+A copy ctor. i = 43
+B dtor. i = 42
+B dtor. i = 41
+A40 + A43
+A ctor. i = 44
+B ctor. i = 45
+B ctor. i = 46
+A dtor. i = 43
+B dtor. i = 46
+B dtor. i = 45
+B ctor. i = 47
+B ctor. i = 48
+A dtor. i = 40
+B dtor. i = 48
+B dtor. i = 47
+B ctor. i = 49
+B ctor. i = 50
+A dtor. i = 37
+B dtor. i = 50
+B dtor. i = 49
+Try a more complex mbarg copy ctors, and a function call
+B ctor. i = 51
+B ctor. i = 52
+A copy ctor. i = 53
+B dtor. i = 52
+B dtor. i = 51
+B ctor. i = 54
+B ctor. i = 55
+A copy ctor. i = 56
+B dtor. i = 55
+B dtor. i = 54
+B ctor. i = 57
+B ctor. i = 58
+A copy ctor. i = 59
+B dtor. i = 58
+B dtor. i = 57
+A ctor. i = 60
+A4 + A60
+A ctor. i = 61
+B ctor. i = 62
+B ctor. i = 63
+A dtor. i = 60
+B dtor. i = 63
+B dtor. i = 62
+A61 + A59
+A ctor. i = 64
+B ctor. i = 65
+B ctor. i = 66
+A dtor. i = 59
+B dtor. i = 66
+B dtor. i = 65
+A64 + A56
+A ctor. i = 67
+B ctor. i = 68
+B ctor. i = 69
+A dtor. i = 56
+B dtor. i = 69
+B dtor. i = 68
+B ctor. i = 70
+B ctor. i = 71
+A copy ctor. i = 72
+B dtor. i = 71
+B dtor. i = 70
+A0 + A72
+A ctor. i = 73
+B ctor. i = 74
+B ctor. i = 75
+A dtor. i = 72
+B dtor. i = 75
+B dtor. i = 74
+A ctor. i = 76
+B ctor. i = 77
+B ctor. i = 78
+A dtor. i = 76
+B dtor. i = 78
+B dtor. i = 77
+B ctor. i = 79
+B ctor. i = 80
+A copy ctor. i = 81
+B dtor. i = 80
+B dtor. i = 79
+B ctor. i = 82
+B ctor. i = 83
+A copy ctor. i = 84
+B dtor. i = 83
+B dtor. i = 82
+B ctor. i = 85
+B ctor. i = 86
+A copy ctor. i = 87
+B dtor. i = 86
+B dtor. i = 85
+A84 + A87
+A ctor. i = 88
+B ctor. i = 89
+B ctor. i = 90
+A dtor. i = 87
+B dtor. i = 90
+B dtor. i = 89
+B ctor. i = 91
+B ctor. i = 92
+A dtor. i = 84
+B dtor. i = 92
+B dtor. i = 91
+B ctor. i = 93
+B ctor. i = 94
+A dtor. i = 81
+B dtor. i = 94
+B dtor. i = 93
+B ctor. i = 95
+B ctor. i = 96
+A dtor. i = 88
+B dtor. i = 96
+B dtor. i = 95
+B ctor. i = 97
+B ctor. i = 98
+A dtor. i = 73
+B dtor. i = 98
+B dtor. i = 97
+B ctor. i = 99
+B ctor. i = 100
+A dtor. i = 67
+B dtor. i = 100
+B dtor. i = 99
+B ctor. i = 101
+B ctor. i = 102
+A dtor. i = 53
+B dtor. i = 102
+B dtor. i = 101
+B ctor. i = 103
+B ctor. i = 104
+A dtor. i = 64
+B dtor. i = 104
+B dtor. i = 103
+B ctor. i = 105
+B ctor. i = 106
+A dtor. i = 61
+B dtor. i = 106
+B dtor. i = 105
+Try temporary expressions, and return UDT
+B ctor. i = 107
+B ctor. i = 108
+A copy ctor. i = 109
+B dtor. i = 108
+B dtor. i = 107
+B ctor. i = 110
+B ctor. i = 111
+A copy ctor. i = 112
+B dtor. i = 111
+B dtor. i = 110
+A ctor. i = 113
+B ctor. i = 114
+B ctor. i = 115
+A copy ctor. i = 116
+B dtor. i = 115
+B dtor. i = 114
+A ctor. i = 117
+A0 + A117
+A ctor. i = 118
+B ctor. i = 119
+B ctor. i = 120
+A dtor. i = 117
+B dtor. i = 120
+B dtor. i = 119
+A118 + A116
+A ctor. i = 121
+B ctor. i = 122
+B ctor. i = 123
+A dtor. i = 116
+B dtor. i = 123
+B dtor. i = 122
+A121 + A113
+A ctor. i = 124
+B ctor. i = 125
+B ctor. i = 126
+A dtor. i = 113
+B dtor. i = 126
+B dtor. i = 125
+A124 + A112
+A ctor. i = 127
+B ctor. i = 128
+B ctor. i = 129
+A dtor. i = 112
+B dtor. i = 129
+B dtor. i = 128
+A127 + A109
+A ctor. i = 130
+B ctor. i = 131
+B ctor. i = 132
+A dtor. i = 109
+B dtor. i = 132
+B dtor. i = 131
+B ctor. i = 133
+B ctor. i = 134
+A dtor. i = 127
+B dtor. i = 134
+B dtor. i = 133
+B ctor. i = 135
+B ctor. i = 136
+A dtor. i = 124
+B dtor. i = 136
+B dtor. i = 135
+B ctor. i = 137
+B ctor. i = 138
+A dtor. i = 121
+B dtor. i = 138
+B dtor. i = 137
+B ctor. i = 139
+B ctor. i = 140
+A dtor. i = 118
+B dtor. i = 140
+B dtor. i = 139
+B ctor. i = 141
+B ctor. i = 142
+A dtor. i = 44
+B dtor. i = 142
+B dtor. i = 141
+B ctor. i = 143
+B ctor. i = 144
+A dtor. i = 26
+B dtor. i = 144
+B dtor. i = 143
+B ctor. i = 145
+B ctor. i = 146
+A dtor. i = 4
+B dtor. i = 146
+B dtor. i = 145
+B ctor. i = 147
+B ctor. i = 148
+A dtor. i = 0
+B dtor. i = 148
+B dtor. i = 147
+B ctor. i = 149
+B ctor. i = 150
+A dtor. i = 130
+B dtor. i = 150
+B dtor. i = 149
+
+ThrowCount = 6 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+A(int) ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+A4 + A9
+A ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+A10 + A8
+A ctor. i = 13
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 8
+B dtor. i = 15
+B dtor. i = 14
+A13 + A7
+A ctor. i = 16
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 7
+B dtor. i = 18
+B dtor. i = 17
+B ctor. i = 19
+B ctor. i = 20
+A copy ctor. i = 21
+B dtor. i = 20
+B dtor. i = 19
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 16
+B dtor. i = 23
+B dtor. i = 22
+B ctor. i = 24
+B ctor. i = 25
+A dtor. i = 13
+B dtor. i = 25
+B dtor. i = 24
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 10
+B dtor. i = 27
+B dtor. i = 26
+Try mbarg copy ctors, and return UDT
+B ctor. i = 28
+B ctor. i = 29
+A copy ctor. i = 30
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 31
+B ctor. i = 32
+A copy ctor. i = 33
+B dtor. i = 32
+B dtor. i = 31
+B ctor. i = 34
+B ctor. i = 35
+A copy ctor. i = 36
+B dtor. i = 35
+B dtor. i = 34
+A33 + A36
+A ctor. i = 37
+B ctor. i = 38
+B ctor. i = 39
+A dtor. i = 36
+B dtor. i = 39
+B dtor. i = 38
+B ctor. i = 40
+B ctor. i = 41
+A dtor. i = 33
+B dtor. i = 41
+B dtor. i = 40
+B ctor. i = 42
+B ctor. i = 43
+A dtor. i = 30
+B dtor. i = 43
+B dtor. i = 42
+Try a more complex mbarg copy ctors, and a function call
+B ctor. i = 44
+B ctor. i = 45
+A copy ctor. i = 46
+B dtor. i = 45
+B dtor. i = 44
+B ctor. i = 47
+B ctor. i = 48
+A copy ctor. i = 49
+B dtor. i = 48
+B dtor. i = 47
+B ctor. i = 50
+B ctor. i = 51
+A copy ctor. i = 52
+B dtor. i = 51
+B dtor. i = 50
+A ctor. i = 53
+A4 + A53
+A ctor. i = 54
+B ctor. i = 55
+B ctor. i = 56
+A dtor. i = 53
+B dtor. i = 56
+B dtor. i = 55
+A54 + A52
+A ctor. i = 57
+B ctor. i = 58
+B ctor. i = 59
+A dtor. i = 52
+B dtor. i = 59
+B dtor. i = 58
+A57 + A49
+A ctor. i = 60
+B ctor. i = 61
+B ctor. i = 62
+A dtor. i = 49
+B dtor. i = 62
+B dtor. i = 61
+B ctor. i = 63
+B ctor. i = 64
+A copy ctor. i = 65
+B dtor. i = 64
+B dtor. i = 63
+A0 + A65
+A ctor. i = 66
+B ctor. i = 67
+B ctor. i = 68
+A dtor. i = 65
+B dtor. i = 68
+B dtor. i = 67
+A ctor. i = 69
+B ctor. i = 70
+B ctor. i = 71
+A dtor. i = 69
+B dtor. i = 71
+B dtor. i = 70
+B ctor. i = 72
+B ctor. i = 73
+A copy ctor. i = 74
+B dtor. i = 73
+B dtor. i = 72
+B ctor. i = 75
+B ctor. i = 76
+A copy ctor. i = 77
+B dtor. i = 76
+B dtor. i = 75
+B ctor. i = 78
+B ctor. i = 79
+A copy ctor. i = 80
+B dtor. i = 79
+B dtor. i = 78
+A77 + A80
+A ctor. i = 81
+B ctor. i = 82
+B ctor. i = 83
+A dtor. i = 80
+B dtor. i = 83
+B dtor. i = 82
+B ctor. i = 84
+B ctor. i = 85
+A dtor. i = 77
+B dtor. i = 85
+B dtor. i = 84
+B ctor. i = 86
+B ctor. i = 87
+A dtor. i = 74
+B dtor. i = 87
+B dtor. i = 86
+B ctor. i = 88
+B ctor. i = 89
+A dtor. i = 81
+B dtor. i = 89
+B dtor. i = 88
+B ctor. i = 90
+B ctor. i = 91
+A dtor. i = 66
+B dtor. i = 91
+B dtor. i = 90
+B ctor. i = 92
+B ctor. i = 93
+A dtor. i = 60
+B dtor. i = 93
+B dtor. i = 92
+B ctor. i = 94
+B ctor. i = 95
+A dtor. i = 46
+B dtor. i = 95
+B dtor. i = 94
+B ctor. i = 96
+B ctor. i = 97
+A dtor. i = 57
+B dtor. i = 97
+B dtor. i = 96
+B ctor. i = 98
+B ctor. i = 99
+A dtor. i = 54
+B dtor. i = 99
+B dtor. i = 98
+Try temporary expressions, and return UDT
+B ctor. i = 100
+B ctor. i = 101
+A copy ctor. i = 102
+B dtor. i = 101
+B dtor. i = 100
+B ctor. i = 103
+B ctor. i = 104
+A copy ctor. i = 105
+B dtor. i = 104
+B dtor. i = 103
+A ctor. i = 106
+B ctor. i = 107
+B ctor. i = 108
+A copy ctor. i = 109
+B dtor. i = 108
+B dtor. i = 107
+A ctor. i = 110
+A0 + A110
+A ctor. i = 111
+B ctor. i = 112
+B ctor. i = 113
+A dtor. i = 110
+B dtor. i = 113
+B dtor. i = 112
+A111 + A109
+A ctor. i = 114
+B ctor. i = 115
+B ctor. i = 116
+A dtor. i = 109
+B dtor. i = 116
+B dtor. i = 115
+A114 + A106
+A ctor. i = 117
+B ctor. i = 118
+B ctor. i = 119
+A dtor. i = 106
+B dtor. i = 119
+B dtor. i = 118
+A117 + A105
+A ctor. i = 120
+B ctor. i = 121
+B ctor. i = 122
+A dtor. i = 105
+B dtor. i = 122
+B dtor. i = 121
+A120 + A102
+A ctor. i = 123
+B ctor. i = 124
+B ctor. i = 125
+A dtor. i = 102
+B dtor. i = 125
+B dtor. i = 124
+B ctor. i = 126
+B ctor. i = 127
+A dtor. i = 120
+B dtor. i = 127
+B dtor. i = 126
+B ctor. i = 128
+B ctor. i = 129
+A dtor. i = 117
+B dtor. i = 129
+B dtor. i = 128
+B ctor. i = 130
+B ctor. i = 131
+A dtor. i = 114
+B dtor. i = 131
+B dtor. i = 130
+B ctor. i = 132
+B ctor. i = 133
+A dtor. i = 111
+B dtor. i = 133
+B dtor. i = 132
+B ctor. i = 134
+B ctor. i = 135
+A dtor. i = 37
+B dtor. i = 135
+B dtor. i = 134
+B ctor. i = 136
+B ctor. i = 137
+A dtor. i = 21
+B dtor. i = 137
+B dtor. i = 136
+B ctor. i = 138
+B ctor. i = 139
+A dtor. i = 4
+B dtor. i = 139
+B dtor. i = 138
+B ctor. i = 140
+B ctor. i = 141
+A dtor. i = 0
+B dtor. i = 141
+B dtor. i = 140
+B ctor. i = 142
+B ctor. i = 143
+A dtor. i = 123
+B dtor. i = 143
+B dtor. i = 142
+
+ThrowCount = 7 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+B ctor. i = 7
+Throwing
+B ctor. i = 8
+B ctor. i = 9
+A dtor. i = 4
+B dtor. i = 9
+B dtor. i = 8
+B ctor. i = 10
+B ctor. i = 11
+A dtor. i = 0
+B dtor. i = 11
+B dtor. i = 10
+In catch
+
+ThrowCount = 8 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+A(int) ctor. i = 7
+A ctor. i = 8
+Throwing
+B ctor. i = 9
+B ctor. i = 10
+A dtor. i = 7
+B dtor. i = 10
+B dtor. i = 9
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 4
+B dtor. i = 12
+B dtor. i = 11
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 0
+B dtor. i = 14
+B dtor. i = 13
+In catch
+
+ThrowCount = 9 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+Throwing
+B dtor. i = 8
+B dtor. i = 7
+B ctor. i = 10
+B ctor. i = 11
+A dtor. i = 4
+B dtor. i = 11
+B dtor. i = 10
+B ctor. i = 12
+B ctor. i = 13
+A dtor. i = 0
+B dtor. i = 13
+B dtor. i = 12
+In catch
+
+ThrowCount = 10 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+A(int) ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+A4 + A9
+A ctor. i = 10
+Throwing
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+B ctor. i = 13
+B ctor. i = 14
+A dtor. i = 8
+B dtor. i = 14
+B dtor. i = 13
+B ctor. i = 15
+B ctor. i = 16
+A dtor. i = 7
+B dtor. i = 16
+B dtor. i = 15
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 4
+B dtor. i = 18
+B dtor. i = 17
+B ctor. i = 19
+B ctor. i = 20
+A dtor. i = 0
+B dtor. i = 20
+B dtor. i = 19
+In catch
+
+ThrowCount = 11 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+A ctor. i = 10
+B ctor. i = 11
+Throwing
+B ctor. i = 12
+B ctor. i = 13
+A dtor. i = 10
+B dtor. i = 13
+B dtor. i = 12
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 9
+B dtor. i = 15
+B dtor. i = 14
+B ctor. i = 16
+B ctor. i = 17
+A dtor. i = 4
+B dtor. i = 17
+B dtor. i = 16
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 0
+B dtor. i = 19
+B dtor. i = 18
+In catch
+
+ThrowCount = 12 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+A(int) ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+A4 + A9
+A ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+A10 + A8
+A ctor. i = 13
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 8
+B dtor. i = 15
+B dtor. i = 14
+A13 + A7
+A ctor. i = 16
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 7
+B dtor. i = 18
+B dtor. i = 17
+B ctor. i = 19
+B ctor. i = 20
+A copy ctor. i = 21
+B dtor. i = 20
+B dtor. i = 19
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 16
+B dtor. i = 23
+B dtor. i = 22
+B ctor. i = 24
+B ctor. i = 25
+A dtor. i = 13
+B dtor. i = 25
+B dtor. i = 24
+B ctor. i = 26
+B ctor. i = 27
+A dtor. i = 10
+B dtor. i = 27
+B dtor. i = 26
+Try mbarg copy ctors, and return UDT
+B ctor. i = 28
+B ctor. i = 29
+A copy ctor. i = 30
+B dtor. i = 29
+B dtor. i = 28
+B ctor. i = 31
+B ctor. i = 32
+A copy ctor. i = 33
+B dtor. i = 32
+B dtor. i = 31
+B ctor. i = 34
+B ctor. i = 35
+A copy ctor. i = 36
+B dtor. i = 35
+B dtor. i = 34
+A33 + A36
+A ctor. i = 37
+B ctor. i = 38
+B ctor. i = 39
+A dtor. i = 36
+B dtor. i = 39
+B dtor. i = 38
+B ctor. i = 40
+B ctor. i = 41
+A dtor. i = 33
+B dtor. i = 41
+B dtor. i = 40
+B ctor. i = 42
+B ctor. i = 43
+A dtor. i = 30
+B dtor. i = 43
+B dtor. i = 42
+Try a more complex mbarg copy ctors, and a function call
+B ctor. i = 44
+B ctor. i = 45
+A copy ctor. i = 46
+B dtor. i = 45
+B dtor. i = 44
+B ctor. i = 47
+B ctor. i = 48
+A copy ctor. i = 49
+B dtor. i = 48
+B dtor. i = 47
+B ctor. i = 50
+B ctor. i = 51
+A copy ctor. i = 52
+B dtor. i = 51
+B dtor. i = 50
+A ctor. i = 53
+A4 + A53
+A ctor. i = 54
+B ctor. i = 55
+B ctor. i = 56
+A dtor. i = 53
+B dtor. i = 56
+B dtor. i = 55
+A54 + A52
+A ctor. i = 57
+B ctor. i = 58
+B ctor. i = 59
+A dtor. i = 52
+B dtor. i = 59
+B dtor. i = 58
+A57 + A49
+A ctor. i = 60
+B ctor. i = 61
+B ctor. i = 62
+A dtor. i = 49
+B dtor. i = 62
+B dtor. i = 61
+B ctor. i = 63
+B ctor. i = 64
+A copy ctor. i = 65
+B dtor. i = 64
+B dtor. i = 63
+A0 + A65
+A ctor. i = 66
+B ctor. i = 67
+B ctor. i = 68
+A dtor. i = 65
+B dtor. i = 68
+B dtor. i = 67
+A ctor. i = 69
+B ctor. i = 70
+B ctor. i = 71
+A dtor. i = 69
+B dtor. i = 71
+B dtor. i = 70
+B ctor. i = 72
+B ctor. i = 73
+A copy ctor. i = 74
+B dtor. i = 73
+B dtor. i = 72
+B ctor. i = 75
+B ctor. i = 76
+A copy ctor. i = 77
+B dtor. i = 76
+B dtor. i = 75
+B ctor. i = 78
+B ctor. i = 79
+A copy ctor. i = 80
+B dtor. i = 79
+B dtor. i = 78
+A77 + A80
+A ctor. i = 81
+B ctor. i = 82
+B ctor. i = 83
+A dtor. i = 80
+B dtor. i = 83
+B dtor. i = 82
+B ctor. i = 84
+B ctor. i = 85
+A dtor. i = 77
+B dtor. i = 85
+B dtor. i = 84
+B ctor. i = 86
+B ctor. i = 87
+A dtor. i = 74
+B dtor. i = 87
+B dtor. i = 86
+B ctor. i = 88
+B ctor. i = 89
+A dtor. i = 81
+B dtor. i = 89
+B dtor. i = 88
+B ctor. i = 90
+B ctor. i = 91
+A dtor. i = 66
+B dtor. i = 91
+B dtor. i = 90
+B ctor. i = 92
+B ctor. i = 93
+A dtor. i = 60
+B dtor. i = 93
+B dtor. i = 92
+B ctor. i = 94
+B ctor. i = 95
+A dtor. i = 46
+B dtor. i = 95
+B dtor. i = 94
+B ctor. i = 96
+B ctor. i = 97
+A dtor. i = 57
+B dtor. i = 97
+B dtor. i = 96
+B ctor. i = 98
+B ctor. i = 99
+A dtor. i = 54
+B dtor. i = 99
+B dtor. i = 98
+Try temporary expressions, and return UDT
+B ctor. i = 100
+B ctor. i = 101
+A copy ctor. i = 102
+B dtor. i = 101
+B dtor. i = 100
+B ctor. i = 103
+B ctor. i = 104
+A copy ctor. i = 105
+B dtor. i = 104
+B dtor. i = 103
+A ctor. i = 106
+B ctor. i = 107
+B ctor. i = 108
+A copy ctor. i = 109
+B dtor. i = 108
+B dtor. i = 107
+A ctor. i = 110
+A0 + A110
+A ctor. i = 111
+B ctor. i = 112
+B ctor. i = 113
+A dtor. i = 110
+B dtor. i = 113
+B dtor. i = 112
+A111 + A109
+A ctor. i = 114
+B ctor. i = 115
+B ctor. i = 116
+A dtor. i = 109
+B dtor. i = 116
+B dtor. i = 115
+A114 + A106
+A ctor. i = 117
+B ctor. i = 118
+B ctor. i = 119
+A dtor. i = 106
+B dtor. i = 119
+B dtor. i = 118
+A117 + A105
+A ctor. i = 120
+B ctor. i = 121
+B ctor. i = 122
+A dtor. i = 105
+B dtor. i = 122
+B dtor. i = 121
+A120 + A102
+A ctor. i = 123
+B ctor. i = 124
+B ctor. i = 125
+A dtor. i = 102
+B dtor. i = 125
+B dtor. i = 124
+B ctor. i = 126
+B ctor. i = 127
+A dtor. i = 120
+B dtor. i = 127
+B dtor. i = 126
+B ctor. i = 128
+B ctor. i = 129
+A dtor. i = 117
+B dtor. i = 129
+B dtor. i = 128
+B ctor. i = 130
+B ctor. i = 131
+A dtor. i = 114
+B dtor. i = 131
+B dtor. i = 130
+B ctor. i = 132
+B ctor. i = 133
+A dtor. i = 111
+B dtor. i = 133
+B dtor. i = 132
+B ctor. i = 134
+B ctor. i = 135
+A dtor. i = 37
+B dtor. i = 135
+B dtor. i = 134
+B ctor. i = 136
+B ctor. i = 137
+A dtor. i = 21
+B dtor. i = 137
+B dtor. i = 136
+B ctor. i = 138
+B ctor. i = 139
+A dtor. i = 4
+B dtor. i = 139
+B dtor. i = 138
+B ctor. i = 140
+B ctor. i = 141
+A dtor. i = 0
+B dtor. i = 141
+B dtor. i = 140
+B ctor. i = 142
+B ctor. i = 143
+A dtor. i = 123
+B dtor. i = 143
+B dtor. i = 142
+
+ThrowCount = 13 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+B ctor. i = 7
+B ctor. i = 8
+A copy ctor. i = 9
+B dtor. i = 8
+B dtor. i = 7
+A ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A copy ctor. i = 13
+Throwing
+B dtor. i = 12
+B dtor. i = 11
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 10
+B dtor. i = 15
+B dtor. i = 14
+B ctor. i = 16
+B ctor. i = 17
+A dtor. i = 9
+B dtor. i = 17
+B dtor. i = 16
+B ctor. i = 18
+B ctor. i = 19
+A dtor. i = 4
+B dtor. i = 19
+B dtor. i = 18
+B ctor. i = 20
+B ctor. i = 21
+A dtor. i = 0
+B dtor. i = 21
+B dtor. i = 20
+In catch
+
+ThrowCount = 14 MaxObjectCount = 151
+Try simple ctor
+A ctor. i = 0
+Try question op ctor
+A(int) ctor. i = 1
+B ctor. i = 2
+B ctor. i = 3
+A copy ctor. i = 4
+B dtor. i = 3
+B dtor. i = 2
+B ctor. i = 5
+B ctor. i = 6
+A dtor. i = 1
+B dtor. i = 6
+B dtor. i = 5
+Try a more complex question op ctor
+A(int) ctor. i = 7
+A ctor. i = 8
+A ctor. i = 9
+A4 + A9
+A ctor. i = 10
+B ctor. i = 11
+B ctor. i = 12
+A dtor. i = 9
+B dtor. i = 12
+B dtor. i = 11
+A10 + A8
+A ctor. i = 13
+B ctor. i = 14
+B ctor. i = 15
+A dtor. i = 8
+B dtor. i = 15
+B dtor. i = 14
+A13 + A7
+A ctor. i = 16
+B ctor. i = 17
+B ctor. i = 18
+A dtor. i = 7
+B dtor. i = 18
+B dtor. i = 17
+B ctor. i = 19
+B ctor. i = 20
+A copy ctor. i = 21
+B dtor. i = 20
+B dtor. i = 19
+B ctor. i = 22
+B ctor. i = 23
+A dtor. i = 16
... 81462 lines suppressed ...