1 | /* Common test support for <stdbit.h> tests. |
2 | Copyright (C) 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 | #ifndef _TST_STDBIT_H |
20 | #define _TST_STDBIT_H |
21 | |
22 | #include <stdbit.h> |
23 | #include <stdbool.h> |
24 | |
25 | #include <array_length.h> |
26 | #include <support/check.h> |
27 | |
28 | struct stdbit_test |
29 | { |
30 | /* The test input. */ |
31 | uint64_t x; |
32 | /* Expected results if that test input is converted to 8, 16, 32 or |
33 | 64 bits and then passed to the function under test for that |
34 | width. */ |
35 | uint64_t res_8, res_16, res_32, res_64; |
36 | }; |
37 | |
38 | #define TEST_TYPE(EXPR, TYPE) \ |
39 | _Static_assert (_Generic ((EXPR), TYPE: 1, default: 0), "bad type") |
40 | |
41 | /* Test a <stdbit.h> function / macro. For each function family, and |
42 | each input type, we test both with and without macros from the |
43 | header being used, both with a possibly wider argument being passed |
44 | (that must be truncated by the prototype) and with the argument |
45 | truncated in the caller, as well as testing the type-generic macro |
46 | (with the argument truncated in the caller). Also test that the |
47 | results have the correct type; also test truncation from |
48 | floating-point arguments (valid for functions, including with macro |
49 | expansion, because the prototype must implicitly convert to integer |
50 | type; not valid for the type-generic macros). Also test that the |
51 | argument is evaluated exactly once. Also test the macros are |
52 | usable (e.g. in typeof) at top level (GCC doesn't allow ({}) |
53 | outside functions: bug 93239). */ |
54 | |
55 | #define TEST_STDBIT_T(FUNC, X, RES, TTYPE, TYPE, SUFFIX) \ |
56 | do \ |
57 | { \ |
58 | TEST_COMPARE (FUNC ## SUFFIX (X), (RES)); \ |
59 | TEST_TYPE (FUNC ## SUFFIX (X), TTYPE); \ |
60 | TEST_COMPARE ((FUNC ## SUFFIX) (X), (RES)); \ |
61 | TEST_TYPE ((FUNC ## SUFFIX) (X), TTYPE); \ |
62 | TEST_COMPARE (FUNC ## SUFFIX ((TYPE) (X)), (RES)); \ |
63 | TEST_TYPE (FUNC ## SUFFIX ((TYPE) (X)), TTYPE); \ |
64 | TEST_COMPARE ((FUNC ## SUFFIX) ((TYPE) (X)), (RES)); \ |
65 | TEST_TYPE ((FUNC ## SUFFIX) ((TYPE) (X)), TTYPE); \ |
66 | TEST_COMPARE (FUNC ((TYPE) (X)), (RES)); \ |
67 | TEST_TYPE (FUNC ((TYPE) (X)), TTYPE); \ |
68 | if (sizeof (TYPE) <= 2) \ |
69 | { \ |
70 | TEST_COMPARE (FUNC ## SUFFIX ((float) (TYPE) (X)), (RES)); \ |
71 | TEST_TYPE (FUNC ## SUFFIX ((float) (TYPE) (X)), TTYPE); \ |
72 | TEST_COMPARE ((FUNC ## SUFFIX) ((float) (TYPE) (X)), (RES)); \ |
73 | TEST_TYPE ((FUNC ## SUFFIX) ((float) (TYPE) (X)), TTYPE); \ |
74 | } \ |
75 | if (sizeof (TYPE) <= 4) \ |
76 | { \ |
77 | TEST_COMPARE (FUNC ## SUFFIX ((double) (TYPE) (X)), (RES)); \ |
78 | TEST_TYPE (FUNC ## SUFFIX ((double) (TYPE) (X)), TTYPE); \ |
79 | TEST_COMPARE ((FUNC ## SUFFIX) ((double) (TYPE) (X)), (RES)); \ |
80 | TEST_TYPE ((FUNC ## SUFFIX) ((double) (TYPE) (X)), TTYPE); \ |
81 | TEST_COMPARE (FUNC ## SUFFIX ((long double) (TYPE) (X)), (RES)); \ |
82 | TEST_TYPE (FUNC ## SUFFIX ((long double) (TYPE) (X)), TTYPE); \ |
83 | TEST_COMPARE ((FUNC ## SUFFIX) ((long double) (TYPE) (X)), (RES)); \ |
84 | TEST_TYPE ((FUNC ## SUFFIX) ((long double) (TYPE) (X)), TTYPE); \ |
85 | } \ |
86 | TYPE xt = (X); \ |
87 | TEST_COMPARE (FUNC ## SUFFIX (xt++), (RES)); \ |
88 | TEST_COMPARE (xt, (TYPE) ((X) + 1)); \ |
89 | xt = (X); \ |
90 | TEST_COMPARE (FUNC (xt++), (RES)); \ |
91 | TEST_COMPARE (xt, (TYPE) ((X) + 1)); \ |
92 | } \ |
93 | while (0) |
94 | |
95 | #define TEST_STDBIT_UI(FUNC, INPUTS) \ |
96 | do \ |
97 | for (int i = 0; i < array_length (INPUTS); i++) \ |
98 | { \ |
99 | uint64_t x = (INPUTS)[i].x; \ |
100 | unsigned int res_8 = (INPUTS)[i].res_8; \ |
101 | unsigned int res_16 = (INPUTS)[i].res_16; \ |
102 | unsigned int res_32 = (INPUTS)[i].res_32; \ |
103 | unsigned int res_64 = (INPUTS)[i].res_64; \ |
104 | unsigned int res_l = (sizeof (long int) == 4 \ |
105 | ? res_32 : res_64); \ |
106 | TEST_STDBIT_T (FUNC, x, res_8, unsigned int, \ |
107 | unsigned char, _uc); \ |
108 | TEST_STDBIT_T (FUNC, x, res_16, unsigned int, \ |
109 | unsigned short, _us); \ |
110 | TEST_STDBIT_T (FUNC, x, res_32, unsigned int, \ |
111 | unsigned int, _ui); \ |
112 | TEST_STDBIT_T (FUNC, x, res_l, unsigned int, \ |
113 | unsigned long int, _ul); \ |
114 | TEST_STDBIT_T (FUNC, x, res_64, unsigned int, \ |
115 | unsigned long long int, _ull); \ |
116 | } \ |
117 | while (0) |
118 | |
119 | #define TEST_STDBIT_BOOL(FUNC, INPUTS) \ |
120 | do \ |
121 | for (int i = 0; i < array_length (INPUTS); i++) \ |
122 | { \ |
123 | uint64_t x = (INPUTS)[i].x; \ |
124 | bool res_8 = (INPUTS)[i].res_8; \ |
125 | bool res_16 = (INPUTS)[i].res_16; \ |
126 | bool res_32 = (INPUTS)[i].res_32; \ |
127 | bool res_64 = (INPUTS)[i].res_64; \ |
128 | bool res_l = (sizeof (long int) == 4 ? res_32 : res_64); \ |
129 | TEST_STDBIT_T (FUNC, x, res_8, _Bool, unsigned char, _uc); \ |
130 | TEST_STDBIT_T (FUNC, x, res_16, _Bool, unsigned short, _us); \ |
131 | TEST_STDBIT_T (FUNC, x, res_32, _Bool, unsigned int, _ui); \ |
132 | TEST_STDBIT_T (FUNC, x, res_l, _Bool, unsigned long int, _ul); \ |
133 | TEST_STDBIT_T (FUNC, x, res_64, _Bool, \ |
134 | unsigned long long int, _ull); \ |
135 | } \ |
136 | while (0) |
137 | |
138 | #define TEST_STDBIT_SAME(FUNC, INPUTS) \ |
139 | do \ |
140 | for (int i = 0; i < array_length (INPUTS); i++) \ |
141 | { \ |
142 | uint64_t x = (INPUTS)[i].x; \ |
143 | unsigned char res_8 = (INPUTS)[i].res_8; \ |
144 | unsigned short res_16 = (INPUTS)[i].res_16; \ |
145 | unsigned int res_32 = (INPUTS)[i].res_32; \ |
146 | unsigned long long int res_64 = (INPUTS)[i].res_64; \ |
147 | unsigned long int res_l = (sizeof (long int) == 4 \ |
148 | ? res_32 : res_64); \ |
149 | TEST_STDBIT_T (FUNC, x, res_8, unsigned char, \ |
150 | unsigned char, _uc); \ |
151 | TEST_STDBIT_T (FUNC, x, res_16, unsigned short, \ |
152 | unsigned short, _us); \ |
153 | TEST_STDBIT_T (FUNC, x, res_32, unsigned int, \ |
154 | unsigned int, _ui); \ |
155 | TEST_STDBIT_T (FUNC, x, res_l, unsigned long int, \ |
156 | unsigned long int, _ul); \ |
157 | TEST_STDBIT_T (FUNC, x, res_64, unsigned long long int, \ |
158 | unsigned long long int, _ull); \ |
159 | } \ |
160 | while (0) |
161 | |
162 | #define TEST_STDBIT_UI_TOPLEVEL(FUNC) \ |
163 | TEST_TYPE (FUNC ## _uc ((unsigned char) 0), unsigned int); \ |
164 | TEST_TYPE (FUNC ((unsigned char) 0), unsigned int); \ |
165 | TEST_TYPE (FUNC ## _us ((unsigned short) 0), unsigned int); \ |
166 | TEST_TYPE (FUNC ((unsigned short) 0), unsigned int); \ |
167 | TEST_TYPE (FUNC ## _ui (0U), unsigned int); \ |
168 | TEST_TYPE (FUNC (0U), unsigned int); \ |
169 | TEST_TYPE (FUNC ## _ul (0UL), unsigned int); \ |
170 | TEST_TYPE (FUNC (0UL), unsigned int); \ |
171 | TEST_TYPE (FUNC ## _ull (0ULL), unsigned int); \ |
172 | TEST_TYPE (FUNC (0ULL), unsigned int) |
173 | |
174 | #define TEST_STDBIT_BOOL_TOPLEVEL(FUNC) \ |
175 | TEST_TYPE (FUNC ## _uc ((unsigned char) 0), _Bool); \ |
176 | TEST_TYPE (FUNC ((unsigned char) 0), _Bool); \ |
177 | TEST_TYPE (FUNC ## _us ((unsigned short) 0), _Bool); \ |
178 | TEST_TYPE (FUNC ((unsigned short) 0), _Bool); \ |
179 | TEST_TYPE (FUNC ## _ui (0U), _Bool); \ |
180 | TEST_TYPE (FUNC (0U), _Bool); \ |
181 | TEST_TYPE (FUNC ## _ul (0UL), _Bool); \ |
182 | TEST_TYPE (FUNC (0UL), _Bool); \ |
183 | TEST_TYPE (FUNC ## _ull (0ULL), _Bool); \ |
184 | TEST_TYPE (FUNC (0ULL), _Bool) |
185 | |
186 | #define TEST_STDBIT_SAME_TOPLEVEL(FUNC) \ |
187 | TEST_TYPE (FUNC ## _uc ((unsigned char) 0), unsigned char); \ |
188 | TEST_TYPE (FUNC ((unsigned char) 0), unsigned char); \ |
189 | TEST_TYPE (FUNC ## _us ((unsigned short) 0), unsigned short); \ |
190 | TEST_TYPE (FUNC ((unsigned short) 0), unsigned short); \ |
191 | TEST_TYPE (FUNC ## _ui (0U), unsigned int); \ |
192 | TEST_TYPE (FUNC (0U), unsigned int); \ |
193 | TEST_TYPE (FUNC ## _ul (0UL), unsigned long int); \ |
194 | TEST_TYPE (FUNC (0UL), unsigned long int); \ |
195 | TEST_TYPE (FUNC ## _ull (0ULL), unsigned long long int); \ |
196 | TEST_TYPE (FUNC (0ULL), unsigned long long int) |
197 | |
198 | #endif |
199 | |