1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: no-exceptions
10 
11 // FIXME: This test fails in MSVC mode due to a stack overflow
12 // XFAIL: msvc
13 
14 // <exception>
15 
16 // class nested_exception;
17 
18 // template <class E> void rethrow_if_nested(const E& e);
19 
20 #include <exception>
21 #include <cstdlib>
22 #include <cassert>
23 
24 #include "test_macros.h"
25 
26 class A
27 {
28     int data_;
29 public:
A(int data)30     explicit A(int data) : data_(data) {}
~A()31     virtual ~A() TEST_NOEXCEPT {}
32 
operator ==(const A & x,const A & y)33     friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
34 };
35 
36 class B
37     : public std::nested_exception,
38       public A
39 {
40 public:
B(int data)41     explicit B(int data) : A(data) {}
B(const B & b)42     B(const B& b) : A(b) {}
43 };
44 
45 class C
46 {
47 public:
~C()48     virtual ~C() {}
operator &() const49     C * operator&() const { assert(false); return nullptr; } // should not be called
50 };
51 
52 class D : private std::nested_exception {};
53 
54 
55 class E1 : public std::nested_exception {};
56 class E2 : public std::nested_exception {};
57 class E : public E1, public E2 {};
58 
main(int,char **)59 int main(int, char**)
60 {
61     {
62         try
63         {
64             A a(3);  // not a polymorphic type --> no effect
65             std::rethrow_if_nested(a);
66             assert(true);
67         }
68         catch (...)
69         {
70             assert(false);
71         }
72     }
73     {
74         try
75         {
76             D s;  // inaccessible base class --> no effect
77             std::rethrow_if_nested(s);
78             assert(true);
79         }
80         catch (...)
81         {
82             assert(false);
83         }
84     }
85     {
86         try
87         {
88             E s;  // ambiguous base class --> no effect
89             std::rethrow_if_nested(s);
90             assert(true);
91         }
92         catch (...)
93         {
94             assert(false);
95         }
96     }
97     {
98         try
99         {
100             throw B(5);
101         }
102         catch (const B& b)
103         {
104             try
105             {
106                 throw b;
107             }
108             catch (const A& a)
109             {
110                 try
111                 {
112                     std::rethrow_if_nested(a);
113                     assert(false);
114                 }
115                 catch (const B& b2)
116                 {
117                     assert(b2 == B(5));
118                 }
119             }
120         }
121     }
122     {
123         try
124         {
125             std::rethrow_if_nested(C());
126             assert(true);
127         }
128         catch (...)
129         {
130             assert(false);
131         }
132     }
133 
134 
135   return 0;
136 }
137