xref: /aosp_15_r20/external/llvm-libc/test/src/stdlib/atexit_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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;
TEST(LlvmLibcAtExit,Basic)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 
TEST(LlvmLibcAtExit,AtExitCallsSysExit)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>
register_atexit_handlers(LIBC_NAMESPACE::cpp::integer_sequence<int,Ts...>)47 void register_atexit_handlers(
48     LIBC_NAMESPACE::cpp::integer_sequence<int, Ts...>) {
49   (LIBC_NAMESPACE::atexit(+[] { arr[size++] = Ts; }), ...);
50 }
51 
getTest()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 
TEST(LlvmLibcAtExit,ReverseOrder)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 
TEST(LlvmLibcAtExit,Many)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 
TEST(LlvmLibcAtExit,HandlerCallsAtExit)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