1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for setjmp and longjmp ----------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker
9*71db0c75SAndroid Build Coastguard Worker #include "src/setjmp/longjmp.h"
10*71db0c75SAndroid Build Coastguard Worker #include "src/setjmp/setjmp_impl.h"
11*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
12*71db0c75SAndroid Build Coastguard Worker
13*71db0c75SAndroid Build Coastguard Worker constexpr int MAX_LOOP = 123;
14*71db0c75SAndroid Build Coastguard Worker int longjmp_called = 0;
15*71db0c75SAndroid Build Coastguard Worker
jump_back(jmp_buf buf,int n)16*71db0c75SAndroid Build Coastguard Worker void jump_back(jmp_buf buf, int n) {
17*71db0c75SAndroid Build Coastguard Worker longjmp_called++;
18*71db0c75SAndroid Build Coastguard Worker LIBC_NAMESPACE::longjmp(buf, n); // Will return |n| out of setjmp
19*71db0c75SAndroid Build Coastguard Worker }
20*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcSetJmpTest,SetAndJumpBack)21*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSetJmpTest, SetAndJumpBack) {
22*71db0c75SAndroid Build Coastguard Worker jmp_buf buf;
23*71db0c75SAndroid Build Coastguard Worker longjmp_called = 0;
24*71db0c75SAndroid Build Coastguard Worker
25*71db0c75SAndroid Build Coastguard Worker // Local variables in setjmp scope should be declared volatile.
26*71db0c75SAndroid Build Coastguard Worker volatile int n = 0;
27*71db0c75SAndroid Build Coastguard Worker // The first time setjmp is called, it should return 0.
28*71db0c75SAndroid Build Coastguard Worker // Subsequent calls will return the value passed to jump_back below.
29*71db0c75SAndroid Build Coastguard Worker if (LIBC_NAMESPACE::setjmp(buf) <= MAX_LOOP) {
30*71db0c75SAndroid Build Coastguard Worker ++n;
31*71db0c75SAndroid Build Coastguard Worker jump_back(buf, n);
32*71db0c75SAndroid Build Coastguard Worker }
33*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(longjmp_called, n);
34*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(n, MAX_LOOP + 1);
35*71db0c75SAndroid Build Coastguard Worker }
36*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcSetJmpTest,SetAndJumpBackValOne)37*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcSetJmpTest, SetAndJumpBackValOne) {
38*71db0c75SAndroid Build Coastguard Worker jmp_buf buf;
39*71db0c75SAndroid Build Coastguard Worker longjmp_called = 0;
40*71db0c75SAndroid Build Coastguard Worker
41*71db0c75SAndroid Build Coastguard Worker int val = LIBC_NAMESPACE::setjmp(buf);
42*71db0c75SAndroid Build Coastguard Worker if (val == 0)
43*71db0c75SAndroid Build Coastguard Worker jump_back(buf, val);
44*71db0c75SAndroid Build Coastguard Worker
45*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(longjmp_called, 1);
46*71db0c75SAndroid Build Coastguard Worker ASSERT_EQ(val, 1);
47*71db0c75SAndroid Build Coastguard Worker }
48