1 //===-- Unittests for atexit ----------------------------------------------===// 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 #include "src/__support/CPP/array.h" 10 #include "src/__support/CPP/utility.h" 11 #include "src/stdlib/_Exit.h" 12 #include "src/stdlib/atexit.h" 13 #include "src/stdlib/exit.h" 14 #include "test/UnitTest/Test.h" 15 16 static int a; 17 TEST(LlvmLibcAtExit, Basic) { 18 // In case tests ever run multiple times. 19 a = 0; 20 21 auto test = [] { 22 int status = LIBC_NAMESPACE::atexit(+[] { 23 if (a != 1) 24 __builtin_trap(); 25 }); 26 status |= LIBC_NAMESPACE::atexit(+[] { a++; }); 27 if (status) 28 __builtin_trap(); 29 30 LIBC_NAMESPACE::exit(0); 31 }; 32 EXPECT_EXITS(test, 0); 33 } 34 35 TEST(LlvmLibcAtExit, AtExitCallsSysExit) { 36 auto test = [] { 37 LIBC_NAMESPACE::atexit(+[] { LIBC_NAMESPACE::_Exit(1); }); 38 LIBC_NAMESPACE::exit(0); 39 }; 40 EXPECT_EXITS(test, 1); 41 } 42 43 static int size; 44 static LIBC_NAMESPACE::cpp::array<int, 256> arr; 45 46 template <int... Ts> 47 void register_atexit_handlers( 48 LIBC_NAMESPACE::cpp::integer_sequence<int, Ts...>) { 49 (LIBC_NAMESPACE::atexit(+[] { arr[size++] = Ts; }), ...); 50 } 51 52 template <int count> constexpr auto getTest() { 53 return [] { 54 LIBC_NAMESPACE::atexit(+[] { 55 if (size != count) 56 __builtin_trap(); 57 for (int i = 0; i < count; i++) 58 if (arr[i] != count - 1 - i) 59 __builtin_trap(); 60 }); 61 register_atexit_handlers( 62 LIBC_NAMESPACE::cpp::make_integer_sequence<int, count>{}); 63 LIBC_NAMESPACE::exit(0); 64 }; 65 } 66 67 TEST(LlvmLibcAtExit, ReverseOrder) { 68 // In case tests ever run multiple times. 69 size = 0; 70 71 auto test = getTest<32>(); 72 EXPECT_EXITS(test, 0); 73 } 74 75 TEST(LlvmLibcAtExit, Many) { 76 // In case tests ever run multiple times. 77 size = 0; 78 79 auto test = getTest<256>(); 80 EXPECT_EXITS(test, 0); 81 } 82 83 TEST(LlvmLibcAtExit, HandlerCallsAtExit) { 84 auto test = [] { 85 LIBC_NAMESPACE::atexit( 86 +[] { LIBC_NAMESPACE::atexit(+[] { LIBC_NAMESPACE::exit(1); }); }); 87 LIBC_NAMESPACE::exit(0); 88 }; 89 EXPECT_EXITS(test, 1); 90 } 91