15a83710eSEric Fiselier //===----------------------------------------------------------------------===// 25a83710eSEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65a83710eSEric Fiselier // 75a83710eSEric Fiselier //===----------------------------------------------------------------------===// 85a83710eSEric Fiselier 9*a21a6ed8SMartin Storsjö // FIXME: This test needs to be rewritten for the MSVC exception_ptr semantics 103e254a6eSEric Fiselier // which copy the exception each time the exception_ptr is copied. 11*a21a6ed8SMartin Storsjö // XFAIL: msvc 129ddcc552SEric Fiselier 138c61114cSLouis Dionne // UNSUPPORTED: no-exceptions 145a83710eSEric Fiselier // <exception> 155a83710eSEric Fiselier 165a83710eSEric Fiselier // exception_ptr current_exception(); 175a83710eSEric Fiselier 185a83710eSEric Fiselier #include <exception> 195a83710eSEric Fiselier #include <cassert> 205a83710eSEric Fiselier 217fc6a556SMarshall Clow #include "test_macros.h" 227fc6a556SMarshall Clow 235a83710eSEric Fiselier struct A 245a83710eSEric Fiselier { 255a83710eSEric Fiselier static int constructed; 265a83710eSEric Fiselier AA275a83710eSEric Fiselier A() {++constructed;} ~AA285a83710eSEric Fiselier ~A() {--constructed;} AA295a83710eSEric Fiselier A(const A&) {++constructed;} 305a83710eSEric Fiselier }; 315a83710eSEric Fiselier 325a83710eSEric Fiselier int A::constructed = 0; 335a83710eSEric Fiselier main(int,char **)342df59c50SJF Bastienint main(int, char**) 355a83710eSEric Fiselier { 365a83710eSEric Fiselier { 375a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 385a83710eSEric Fiselier assert(p == nullptr); 395a83710eSEric Fiselier } 405a83710eSEric Fiselier { 415a83710eSEric Fiselier try 425a83710eSEric Fiselier { 435a83710eSEric Fiselier assert(A::constructed == 0); 445a83710eSEric Fiselier throw A(); 455a83710eSEric Fiselier assert(false); 465a83710eSEric Fiselier } 475a83710eSEric Fiselier catch (...) 485a83710eSEric Fiselier { 495a83710eSEric Fiselier assert(A::constructed == 1); 505a83710eSEric Fiselier } 515a83710eSEric Fiselier assert(A::constructed == 0); 525a83710eSEric Fiselier } 535a83710eSEric Fiselier assert(A::constructed == 0); 545a83710eSEric Fiselier { 555a83710eSEric Fiselier std::exception_ptr p2; 565a83710eSEric Fiselier try 575a83710eSEric Fiselier { 585a83710eSEric Fiselier assert(A::constructed == 0); 595a83710eSEric Fiselier throw A(); 605a83710eSEric Fiselier assert(false); 615a83710eSEric Fiselier } 625a83710eSEric Fiselier catch (...) 635a83710eSEric Fiselier { 645a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 655a83710eSEric Fiselier assert(A::constructed == 1); 665a83710eSEric Fiselier assert(p != nullptr); 675a83710eSEric Fiselier p2 = std::current_exception(); 685a83710eSEric Fiselier assert(A::constructed == 1); 695a83710eSEric Fiselier assert(p == p2); 705a83710eSEric Fiselier } 715a83710eSEric Fiselier assert(A::constructed == 1); 725a83710eSEric Fiselier } 735a83710eSEric Fiselier assert(A::constructed == 0); 745a83710eSEric Fiselier { 755a83710eSEric Fiselier std::exception_ptr p2; 765a83710eSEric Fiselier try 775a83710eSEric Fiselier { 785a83710eSEric Fiselier assert(A::constructed == 0); 795a83710eSEric Fiselier throw A(); 805a83710eSEric Fiselier assert(false); 815a83710eSEric Fiselier } 82fb42f4c4SEric Fiselier catch (A&) 835a83710eSEric Fiselier { 845a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 855a83710eSEric Fiselier assert(A::constructed == 1); 865a83710eSEric Fiselier assert(p != nullptr); 875a83710eSEric Fiselier p2 = std::current_exception(); 885a83710eSEric Fiselier assert(A::constructed == 1); 895a83710eSEric Fiselier assert(p == p2); 905a83710eSEric Fiselier } 915a83710eSEric Fiselier assert(A::constructed == 1); 925a83710eSEric Fiselier } 935a83710eSEric Fiselier assert(A::constructed == 0); 945a83710eSEric Fiselier { 955a83710eSEric Fiselier std::exception_ptr p2; 965a83710eSEric Fiselier try 975a83710eSEric Fiselier { 985a83710eSEric Fiselier assert(A::constructed == 0); 995a83710eSEric Fiselier throw A(); 1005a83710eSEric Fiselier assert(false); 1015a83710eSEric Fiselier } 102fb42f4c4SEric Fiselier catch (A) 1035a83710eSEric Fiselier { 1045a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 1055a83710eSEric Fiselier assert(A::constructed == 2); 1065a83710eSEric Fiselier assert(p != nullptr); 1075a83710eSEric Fiselier p2 = std::current_exception(); 1085a83710eSEric Fiselier assert(A::constructed == 2); 1095a83710eSEric Fiselier assert(p == p2); 1105a83710eSEric Fiselier } 1115a83710eSEric Fiselier assert(A::constructed == 1); 1125a83710eSEric Fiselier } 1135a83710eSEric Fiselier assert(A::constructed == 0); 1145a83710eSEric Fiselier { 1155a83710eSEric Fiselier try 1165a83710eSEric Fiselier { 1175a83710eSEric Fiselier assert(A::constructed == 0); 1185a83710eSEric Fiselier throw A(); 1195a83710eSEric Fiselier assert(false); 1205a83710eSEric Fiselier } 1215a83710eSEric Fiselier catch (...) 1225a83710eSEric Fiselier { 1235a83710eSEric Fiselier assert(A::constructed == 1); 1245a83710eSEric Fiselier try 1255a83710eSEric Fiselier { 1265a83710eSEric Fiselier assert(A::constructed == 1); 1275a83710eSEric Fiselier throw; 1285a83710eSEric Fiselier assert(false); 1295a83710eSEric Fiselier } 1305a83710eSEric Fiselier catch (...) 1315a83710eSEric Fiselier { 1325a83710eSEric Fiselier assert(A::constructed == 1); 1335a83710eSEric Fiselier } 1345a83710eSEric Fiselier assert(A::constructed == 1); 1355a83710eSEric Fiselier } 1365a83710eSEric Fiselier assert(A::constructed == 0); 1375a83710eSEric Fiselier } 1385a83710eSEric Fiselier assert(A::constructed == 0); 1395a83710eSEric Fiselier { 1405a83710eSEric Fiselier try 1415a83710eSEric Fiselier { 1425a83710eSEric Fiselier assert(A::constructed == 0); 1435a83710eSEric Fiselier throw A(); 1445a83710eSEric Fiselier assert(false); 1455a83710eSEric Fiselier } 1465a83710eSEric Fiselier catch (...) 1475a83710eSEric Fiselier { 1485a83710eSEric Fiselier assert(A::constructed == 1); 1495a83710eSEric Fiselier try 1505a83710eSEric Fiselier { 1515a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 1525a83710eSEric Fiselier assert(A::constructed == 1); 1535a83710eSEric Fiselier assert(p != nullptr); 1545a83710eSEric Fiselier throw; 1555a83710eSEric Fiselier assert(false); 1565a83710eSEric Fiselier } 1575a83710eSEric Fiselier catch (...) 1585a83710eSEric Fiselier { 1595a83710eSEric Fiselier assert(A::constructed == 1); 1605a83710eSEric Fiselier } 1615a83710eSEric Fiselier assert(A::constructed == 1); 1625a83710eSEric Fiselier } 1635a83710eSEric Fiselier assert(A::constructed == 0); 1645a83710eSEric Fiselier } 1655a83710eSEric Fiselier assert(A::constructed == 0); 1665a83710eSEric Fiselier { 1675a83710eSEric Fiselier try 1685a83710eSEric Fiselier { 1695a83710eSEric Fiselier assert(A::constructed == 0); 1705a83710eSEric Fiselier throw A(); 1715a83710eSEric Fiselier assert(false); 1725a83710eSEric Fiselier } 1735a83710eSEric Fiselier catch (...) 1745a83710eSEric Fiselier { 1755a83710eSEric Fiselier assert(A::constructed == 1); 1765a83710eSEric Fiselier try 1775a83710eSEric Fiselier { 1785a83710eSEric Fiselier assert(A::constructed == 1); 1795a83710eSEric Fiselier throw; 1805a83710eSEric Fiselier assert(false); 1815a83710eSEric Fiselier } 1825a83710eSEric Fiselier catch (...) 1835a83710eSEric Fiselier { 1845a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 1855a83710eSEric Fiselier assert(A::constructed == 1); 1865a83710eSEric Fiselier assert(p != nullptr); 1875a83710eSEric Fiselier } 1885a83710eSEric Fiselier assert(A::constructed == 1); 1895a83710eSEric Fiselier } 1905a83710eSEric Fiselier assert(A::constructed == 0); 1915a83710eSEric Fiselier } 1925a83710eSEric Fiselier assert(A::constructed == 0); 1935a83710eSEric Fiselier { 1945a83710eSEric Fiselier try 1955a83710eSEric Fiselier { 1965a83710eSEric Fiselier assert(A::constructed == 0); 1975a83710eSEric Fiselier throw A(); 1985a83710eSEric Fiselier assert(false); 1995a83710eSEric Fiselier } 2005a83710eSEric Fiselier catch (...) 2015a83710eSEric Fiselier { 2025a83710eSEric Fiselier assert(A::constructed == 1); 2035a83710eSEric Fiselier try 2045a83710eSEric Fiselier { 2055a83710eSEric Fiselier assert(A::constructed == 1); 2065a83710eSEric Fiselier throw; 2075a83710eSEric Fiselier assert(false); 2085a83710eSEric Fiselier } 2095a83710eSEric Fiselier catch (...) 2105a83710eSEric Fiselier { 2115a83710eSEric Fiselier assert(A::constructed == 1); 2125a83710eSEric Fiselier } 2135a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 2145a83710eSEric Fiselier assert(A::constructed == 1); 2155a83710eSEric Fiselier assert(p != nullptr); 2165a83710eSEric Fiselier } 2175a83710eSEric Fiselier assert(A::constructed == 0); 2185a83710eSEric Fiselier } 2195a83710eSEric Fiselier assert(A::constructed == 0); 2205a83710eSEric Fiselier { 2215a83710eSEric Fiselier try 2225a83710eSEric Fiselier { 2235a83710eSEric Fiselier assert(A::constructed == 0); 2245a83710eSEric Fiselier throw A(); 2255a83710eSEric Fiselier assert(false); 2265a83710eSEric Fiselier } 2275a83710eSEric Fiselier catch (...) 2285a83710eSEric Fiselier { 2295a83710eSEric Fiselier assert(A::constructed == 1); 2305a83710eSEric Fiselier try 2315a83710eSEric Fiselier { 2325a83710eSEric Fiselier assert(A::constructed == 1); 2335a83710eSEric Fiselier throw; 2345a83710eSEric Fiselier assert(false); 2355a83710eSEric Fiselier } 2365a83710eSEric Fiselier catch (...) 2375a83710eSEric Fiselier { 2385a83710eSEric Fiselier assert(A::constructed == 1); 2395a83710eSEric Fiselier } 2405a83710eSEric Fiselier assert(A::constructed == 1); 2415a83710eSEric Fiselier } 2425a83710eSEric Fiselier std::exception_ptr p = std::current_exception(); 2435a83710eSEric Fiselier assert(A::constructed == 0); 2445a83710eSEric Fiselier assert(p == nullptr); 2455a83710eSEric Fiselier } 2465a83710eSEric Fiselier assert(A::constructed == 0); 2475a83710eSEric Fiselier { 2485a83710eSEric Fiselier std::exception_ptr p; 2495a83710eSEric Fiselier try 2505a83710eSEric Fiselier { 2515a83710eSEric Fiselier assert(A::constructed == 0); 2525a83710eSEric Fiselier throw A(); 2535a83710eSEric Fiselier assert(false); 2545a83710eSEric Fiselier } 2555a83710eSEric Fiselier catch (...) 2565a83710eSEric Fiselier { 2575a83710eSEric Fiselier assert(A::constructed == 1); 2585a83710eSEric Fiselier try 2595a83710eSEric Fiselier { 2605a83710eSEric Fiselier assert(A::constructed == 1); 2615a83710eSEric Fiselier throw; 2625a83710eSEric Fiselier assert(false); 2635a83710eSEric Fiselier } 2645a83710eSEric Fiselier catch (...) 2655a83710eSEric Fiselier { 2665a83710eSEric Fiselier p = std::current_exception(); 2675a83710eSEric Fiselier assert(A::constructed == 1); 2685a83710eSEric Fiselier } 2695a83710eSEric Fiselier assert(A::constructed == 1); 2705a83710eSEric Fiselier } 2715a83710eSEric Fiselier assert(A::constructed == 1); 2725a83710eSEric Fiselier assert(p != nullptr); 2735a83710eSEric Fiselier } 2745a83710eSEric Fiselier assert(A::constructed == 0); 2752df59c50SJF Bastien 2762df59c50SJF Bastien return 0; 2775a83710eSEric Fiselier } 278