1ab3cbe4bSSiva Chandra Reddy //===-- Unittests for feraiseexcept with exceptions enabled ---------------===//
2ab3cbe4bSSiva Chandra Reddy //
3ab3cbe4bSSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ab3cbe4bSSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
5ab3cbe4bSSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ab3cbe4bSSiva Chandra Reddy //
7ab3cbe4bSSiva Chandra Reddy //===----------------------------------------------------------------------===//
8ab3cbe4bSSiva Chandra Reddy 
9ab3cbe4bSSiva Chandra Reddy #include "src/fenv/feclearexcept.h"
10ab3cbe4bSSiva Chandra Reddy #include "src/fenv/feraiseexcept.h"
11ab3cbe4bSSiva Chandra Reddy #include "src/fenv/fetestexcept.h"
12ab3cbe4bSSiva Chandra Reddy 
13ab3cbe4bSSiva Chandra Reddy #include "utils/FPUtil/FEnv.h"
14ab3cbe4bSSiva Chandra Reddy #include "utils/UnitTest/Test.h"
15ab3cbe4bSSiva Chandra Reddy 
16ab3cbe4bSSiva Chandra Reddy #include <fenv.h>
17ab3cbe4bSSiva Chandra Reddy #include <signal.h>
18ab3cbe4bSSiva Chandra Reddy 
19ab3cbe4bSSiva Chandra Reddy // This test enables an exception and verifies that raising that exception
20ab3cbe4bSSiva Chandra Reddy // triggers SIGFPE.
21*1df0dbfcSMichael Jones TEST(LlvmLibcExceptionStatusTest, RaiseAndCrash) {
22ab3cbe4bSSiva Chandra Reddy   // TODO: Install a floating point exception handler and verify that the
23ab3cbe4bSSiva Chandra Reddy   // the expected exception was raised. One will have to longjmp back from
24ab3cbe4bSSiva Chandra Reddy   // that exception handler, so such a testing can be done after we have
25ab3cbe4bSSiva Chandra Reddy   // longjmp implemented.
26ab3cbe4bSSiva Chandra Reddy 
27ab3cbe4bSSiva Chandra Reddy   int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
28ab3cbe4bSSiva Chandra Reddy                    FE_UNDERFLOW};
29ab3cbe4bSSiva Chandra Reddy 
30ab3cbe4bSSiva Chandra Reddy   for (int e : excepts) {
31ab3cbe4bSSiva Chandra Reddy     ASSERT_DEATH(
32ab3cbe4bSSiva Chandra Reddy         [=] {
33ab3cbe4bSSiva Chandra Reddy           __llvm_libc::fputil::disableExcept(FE_ALL_EXCEPT);
34ab3cbe4bSSiva Chandra Reddy           __llvm_libc::fputil::enableExcept(e);
35ab3cbe4bSSiva Chandra Reddy           ASSERT_EQ(__llvm_libc::feclearexcept(FE_ALL_EXCEPT), 0);
36ab3cbe4bSSiva Chandra Reddy           // Raising all exceptions except |e| should not call the
37ab3cbe4bSSiva Chandra Reddy           // SIGFPE handler. They should set the exception flag though,
38ab3cbe4bSSiva Chandra Reddy           // so we verify that.
39ab3cbe4bSSiva Chandra Reddy           int others = FE_ALL_EXCEPT & ~e;
40ab3cbe4bSSiva Chandra Reddy           ASSERT_EQ(__llvm_libc::feraiseexcept(others), 0);
41ab3cbe4bSSiva Chandra Reddy           ASSERT_EQ(__llvm_libc::fetestexcept(others), others);
42ab3cbe4bSSiva Chandra Reddy 
43ab3cbe4bSSiva Chandra Reddy           // We don't check the return value when raising |e| as
44ab3cbe4bSSiva Chandra Reddy           // feraiseexcept will not return when it raises an enabled
45ab3cbe4bSSiva Chandra Reddy           // exception.
46ab3cbe4bSSiva Chandra Reddy           __llvm_libc::feraiseexcept(e);
47ab3cbe4bSSiva Chandra Reddy         },
48ab3cbe4bSSiva Chandra Reddy         SIGFPE);
49ab3cbe4bSSiva Chandra Reddy   }
50ab3cbe4bSSiva Chandra Reddy }
51