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 // <exception>
11 
12 // class nested_exception;
13 
14 // template<class T> void throw_with_nested [[noreturn]] (T&& t);
15 
16 #include <exception>
17 #include <cstdlib>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 
22 class A
23 {
24     int data_;
25 public:
A(int data)26     explicit A(int data) : data_(data) {}
27 
operator ==(const A & x,const A & y)28     friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
29 };
30 
31 class B
32     : public std::nested_exception
33 {
34     int data_;
35 public:
B(int data)36     explicit B(int data) : data_(data) {}
37 
operator ==(const B & x,const B & y)38     friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;}
39 };
40 
41 #if TEST_STD_VER > 11
42 struct Final final {};
43 #endif
44 
main(int,char **)45 int main(int, char**)
46 {
47     {
48         try
49         {
50             A a(3);
51             std::throw_with_nested(a);
52             assert(false);
53         }
54         catch (const A& a)
55         {
56             assert(a == A(3));
57         }
58     }
59     {
60         try
61         {
62             A a(4);
63             std::throw_with_nested(a);
64             assert(false);
65         }
66         catch (const std::nested_exception& e)
67         {
68             assert(e.nested_ptr() == nullptr);
69         }
70     }
71     {
72         try
73         {
74             B b(5);
75             std::throw_with_nested(b);
76             assert(false);
77         }
78         catch (const B& b)
79         {
80             assert(b == B(5));
81         }
82     }
83     {
84         try
85         {
86             B b(6);
87             std::throw_with_nested(b);
88             assert(false);
89         }
90         catch (const std::nested_exception& e)
91         {
92             assert(e.nested_ptr() == nullptr);
93             const B& b = dynamic_cast<const B&>(e);
94             assert(b == B(6));
95         }
96     }
97     {
98         try
99         {
100             int i = 7;
101             std::throw_with_nested(i);
102             assert(false);
103         }
104         catch (int i)
105         {
106             assert(i == 7);
107         }
108     }
109     {
110         try
111         {
112             std::throw_with_nested("String literal");
113             assert(false);
114         }
115         catch (const char *)
116         {
117         }
118     }
119 #if TEST_STD_VER > 11
120     {
121         try
122         {
123             std::throw_with_nested(Final());
124             assert(false);
125         }
126         catch (const Final &)
127         {
128         }
129     }
130 #endif
131 
132   return 0;
133 }
134