111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===//
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//                     The LLVM Compiler Infrastructure
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is dual licensed under the MIT and the University of Illinois Open
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Source Licenses. See LICENSE.TXT for details.
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//===----------------------------------------------------------------------===//
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// XFAIL: libcpp-no-exceptions
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <exception>
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// class nested_exception;
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// template<class T> void throw_with_nested [[noreturn]] (T&& t);
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <exception>
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cstdlib>
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cassert>
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass A
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int data_;
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    explicit A(int data) : data_(data) {}
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    friend bool operator==(const A& x, const A& y) {return x.data_ == y.data_;}
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass B
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : public std::nested_exception
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int data_;
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    explicit B(int data) : data_(data) {}
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    friend bool operator==(const B& x, const B& y) {return x.data_ == y.data_;}
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus > 201103L
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Final final {};
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertint main()
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        try
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            A a(3);
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            std::throw_with_nested(a);
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(false);
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        catch (const A& a)
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(a == A(3));
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        try
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            A a(4);
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            std::throw_with_nested(a);
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(false);
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        catch (const std::nested_exception& e)
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(e.nested_ptr() == nullptr);
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        try
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            B b(5);
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            std::throw_with_nested(b);
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(false);
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        catch (const B& b)
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(b == B(5));
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        try
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            B b(6);
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            std::throw_with_nested(b);
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(false);
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        catch (const std::nested_exception& e)
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(e.nested_ptr() == nullptr);
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            const B& b = dynamic_cast<const B&>(e);
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(b == B(6));
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        try
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            int i = 7;
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            std::throw_with_nested(i);
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(false);
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        catch (int i)
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(i == 7);
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus > 201103L
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        try
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            std::throw_with_nested(Final());
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            assert(false);
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        catch (const Final &)
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
121