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
28struct 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

source code of glibc/stdlib/tst-stdbit.h