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

source code of libc/test/src/stdlib/atexit_test.cpp