1e434b34fSJonathan Roelofs //===--------------------- catch_pointer_nullptr.cpp ----------------------===//
2e434b34fSJonathan Roelofs //
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
6e434b34fSJonathan Roelofs //
7e434b34fSJonathan Roelofs //===----------------------------------------------------------------------===//
8e434b34fSJonathan Roelofs 
9*60ba1fefSLouis Dionne // Catching an exception thrown as nullptr was not properly handled before
10*60ba1fefSLouis Dionne // 2f984cab4fa7, which landed in macOS 10.13
11*60ba1fefSLouis Dionne // XFAIL: with_system_cxx_lib=macosx10.12
12*60ba1fefSLouis Dionne // XFAIL: with_system_cxx_lib=macosx10.11
13*60ba1fefSLouis Dionne // XFAIL: with_system_cxx_lib=macosx10.10
14*60ba1fefSLouis Dionne // XFAIL: with_system_cxx_lib=macosx10.9
15*60ba1fefSLouis Dionne 
1631cbe0f2SLouis Dionne // UNSUPPORTED: c++03
178c61114cSLouis Dionne // UNSUPPORTED: no-exceptions
18c79a8f77SEric Fiselier 
19e434b34fSJonathan Roelofs #include <cassert>
201b00fc5dSEric Fiselier #include <cstdlib>
211b00fc5dSEric Fiselier 
221b00fc5dSEric Fiselier struct A {};
23e434b34fSJonathan Roelofs 
24e434b34fSJonathan Roelofs void test1()
25e434b34fSJonathan Roelofs {
26e434b34fSJonathan Roelofs     try
27e434b34fSJonathan Roelofs     {
28e434b34fSJonathan Roelofs         throw nullptr;
29e434b34fSJonathan Roelofs         assert(false);
30e434b34fSJonathan Roelofs     }
312f984cabSRichard Smith     catch (int* p)
32e434b34fSJonathan Roelofs     {
332f984cabSRichard Smith         assert(!p);
34e434b34fSJonathan Roelofs     }
35e434b34fSJonathan Roelofs     catch (long*)
36e434b34fSJonathan Roelofs     {
37e434b34fSJonathan Roelofs         assert(false);
38e434b34fSJonathan Roelofs     }
39e434b34fSJonathan Roelofs }
40e434b34fSJonathan Roelofs 
41e434b34fSJonathan Roelofs void test2()
42e434b34fSJonathan Roelofs {
43e434b34fSJonathan Roelofs     try
44e434b34fSJonathan Roelofs     {
45e434b34fSJonathan Roelofs         throw nullptr;
46e434b34fSJonathan Roelofs         assert(false);
47e434b34fSJonathan Roelofs     }
482f984cabSRichard Smith     catch (A* p)
49e434b34fSJonathan Roelofs     {
502f984cabSRichard Smith         assert(!p);
51e434b34fSJonathan Roelofs     }
52e434b34fSJonathan Roelofs     catch (int*)
53e434b34fSJonathan Roelofs     {
54e434b34fSJonathan Roelofs         assert(false);
55e434b34fSJonathan Roelofs     }
56e434b34fSJonathan Roelofs }
57e434b34fSJonathan Roelofs 
581b00fc5dSEric Fiselier template <class Catch>
591b00fc5dSEric Fiselier void catch_nullptr_test() {
601b00fc5dSEric Fiselier   try {
611b00fc5dSEric Fiselier     throw nullptr;
621b00fc5dSEric Fiselier     assert(false);
632f984cabSRichard Smith   } catch (Catch c) {
642f984cabSRichard Smith     assert(!c);
651b00fc5dSEric Fiselier   } catch (...) {
661b00fc5dSEric Fiselier     assert(false);
671b00fc5dSEric Fiselier   }
681b00fc5dSEric Fiselier }
691b00fc5dSEric Fiselier 
70e434b34fSJonathan Roelofs 
71504bc07dSLouis Dionne int main(int, char**)
72e434b34fSJonathan Roelofs {
731b00fc5dSEric Fiselier   // catch naked nullptrs
74e434b34fSJonathan Roelofs   test1();
75e434b34fSJonathan Roelofs   test2();
761b00fc5dSEric Fiselier 
771b00fc5dSEric Fiselier   catch_nullptr_test<int*>();
781b00fc5dSEric Fiselier   catch_nullptr_test<int**>();
791b00fc5dSEric Fiselier   catch_nullptr_test<int A::*>();
801b00fc5dSEric Fiselier   catch_nullptr_test<const int A::*>();
811b00fc5dSEric Fiselier   catch_nullptr_test<int A::**>();
82504bc07dSLouis Dionne 
83504bc07dSLouis Dionne   return 0;
84e434b34fSJonathan Roelofs }
85