]>
Commit | Line | Data |
---|---|---|
b34b46b8 JM |
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 |