1/* Test fegetexceptflag and fesetexceptflag: exception traps enabled.
2 Copyright (C) 2016-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <fenv.h>
20#include <stdio.h>
21#include <math-tests.h>
22#include <math-barriers.h>
23
24static int
25do_test (void)
26{
27 int result = 0;
28
29 fedisableexcept (FE_ALL_EXCEPT);
30 int ret = feraiseexcept (FE_ALL_EXCEPT);
31 if (ret != 0)
32 {
33 if (EXCEPTION_TESTS (float))
34 {
35 puts (s: "feraiseexcept (FE_ALL_EXCEPT) failed");
36 result = 1;
37 return result;
38 }
39 else
40 {
41 puts (s: "feraiseexcept (FE_ALL_EXCEPT) unsupported, cannot test");
42 return 77;
43 }
44 }
45 fexcept_t saved;
46 ret = fegetexceptflag (flagp: &saved, FE_ALL_EXCEPT);
47 if (ret != 0)
48 {
49 puts (s: "fegetexceptflag failed");
50 result = 1;
51 return result;
52 }
53 feclearexcept (FE_ALL_EXCEPT);
54
55 ret = feenableexcept (FE_ALL_EXCEPT);
56 if (!EXCEPTION_ENABLE_SUPPORTED (FE_ALL_EXCEPT) && (ret == -1))
57 {
58 puts (s: "feenableexcept (FE_ALL_EXCEPT) not supported, cannot test");
59 return 77;
60 }
61 else if (ret != 0)
62 {
63 puts (s: "feenableexcept (FE_ALL_EXCEPT) failed");
64 result = 1;
65 }
66
67 /* The test is that this does not cause exception traps. For architectures
68 where setting the exception might result in traps the function should
69 return a nonzero value.
70 Also check if the function does not alter the exception mask. */
71 ret = fesetexceptflag (flagp: &saved, FE_ALL_EXCEPT);
72
73 _Static_assert (!(EXCEPTION_SET_FORCES_TRAP && !EXCEPTION_TESTS(float)),
74 "EXCEPTION_SET_FORCES_TRAP only makes sense if the "
75 "architecture suports exceptions");
76 {
77 int exc_before = fegetexcept ();
78 ret = fesetexceptflag (flagp: &saved, FE_ALL_EXCEPT);
79 int exc_after = fegetexcept ();
80 if (exc_before != exc_after)
81 {
82 puts (s: "fesetexceptflag (FE_ALL_EXCEPT) changed the exceptions mask");
83 return 1;
84 }
85 }
86
87 /* Execute some floating-point operations, since on some CPUs exceptions
88 triggers a trap only at the next floating-point instruction. */
89 volatile double a = 1.0;
90 volatile double b = a + a;
91 math_force_eval (b);
92 volatile long double al = 1.0L;
93 volatile long double bl = al + al;
94 math_force_eval (bl);
95
96 if (ret != 0 && !EXCEPTION_SET_FORCES_TRAP)
97 {
98 puts (s: "fesetexceptflag failed");
99 result = 1;
100 }
101 feclearexcept (FE_ALL_EXCEPT);
102
103 return result;
104}
105
106#define TEST_FUNCTION do_test ()
107#include "../test-skeleton.c"
108

source code of glibc/math/test-fexcept-traps.c