1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <inttypes.h>
6 #include <limits.h>
7 #include <signal.h>
8 #include <stdint.h>
9 #include <type_traits>
10 #include <wchar.h>
11
12 #include <unittest/unittest.h>
13
14 // stdint.h defines the following types:
15 // Fixed width types:
16 // int8_t
17 // int16_t
18 // int32_t
19 // int64_t
20 // uint8_t
21 // uint16_t
22 // uint32_t
23 // uint64_t
24
25 // Minimum width types:
26 // int_least8_t
27 // int_least16_t
28 // int_least32_t
29 // int_least64_t
30 // uint_least8_t
31 // uint_least16_t
32 // uint_least32_t
33 // uint_least64_t
34
35 // Fast minimum width types:
36 // int_fast8_t
37 // int_fast16_t
38 // int_fast32_t
39 // int_fast64_t
40 // uint_fast8_t
41 // uint_fast16_t
42 // uint_fast32_t
43 // uint_fast64_t
44
45 // Pointer-sized types:
46 // intptr_t
47 // uintptr_t
48
49 // Maximum-width types:
50 // intmax_t
51 // uintmax_t
52
53 // stddef.h defines the following types:
54 // ptrdiff_t
55 // size_t
56 // wchar_t
57
58 // signal.h defines the following type:
59 // sig_atomic_t
60
61 // Test sizes.
62 static_assert(CHAR_BIT == 8, "");
63
64 static_assert(sizeof(int8_t) == 1, "");
65 static_assert(sizeof(int16_t) == 2, "");
66 static_assert(sizeof(int32_t) == 4, "");
67 static_assert(sizeof(int64_t) == 8, "");
68 static_assert(sizeof(uint8_t) == 1, "");
69 static_assert(sizeof(uint16_t) == 2, "");
70 static_assert(sizeof(uint32_t) == 4, "");
71 static_assert(sizeof(uint64_t) == 8, "");
72
73 static_assert(sizeof(int_least8_t) >= 1, "");
74 static_assert(sizeof(int_least16_t) >= 2, "");
75 static_assert(sizeof(int_least32_t) >= 4, "");
76 static_assert(sizeof(int_least64_t) >= 8, "");
77 static_assert(sizeof(uint_least8_t) >= 1, "");
78 static_assert(sizeof(uint_least16_t) >= 2, "");
79 static_assert(sizeof(uint_least32_t) >= 4, "");
80 static_assert(sizeof(uint_least64_t) >= 8, "");
81
82 static_assert(sizeof(int_fast8_t) >= 1, "");
83 static_assert(sizeof(int_fast16_t) >= 2, "");
84 static_assert(sizeof(int_fast32_t) >= 4, "");
85 static_assert(sizeof(int_fast64_t) >= 8, "");
86 static_assert(sizeof(uint_fast8_t) >= 1, "");
87 static_assert(sizeof(uint_fast16_t) >= 2, "");
88 static_assert(sizeof(uint_fast32_t) >= 4, "");
89 static_assert(sizeof(uint_fast64_t) >= 8, "");
90
91 static_assert(sizeof(intptr_t) == sizeof(void*), "");
92 static_assert(sizeof(uintptr_t) == sizeof(void*), "");
93
94 static_assert(sizeof(intmax_t) == 8, "");
95 static_assert(sizeof(uintmax_t) == 8, "");
96
97 static_assert(sizeof(ptrdiff_t) == sizeof(void*), "");
98 static_assert(sizeof(size_t) == sizeof(void*), "");
99
100 // No interesting guarantees can be made about the sizes of these:
101 // wchar_t
102 // sig_atomic_t
103
104 // Check maximums.
105 #define CHECK_MAX_TYPE(type, TYPE, max_t, MAX) \
106 ((max_t)TYPE##_MAX == (MAX >> (CHAR_BIT * (sizeof(max_t) - sizeof(type)))))
107
108 #define CHECK_MAX_UNSIGNED(type, TYPE) CHECK_MAX_TYPE(type, TYPE, uintmax_t, UINTMAX_MAX)
109 #define CHECK_MAX_SIGNED(type, TYPE) CHECK_MAX_TYPE(type, TYPE, intmax_t, INTMAX_MAX)
110
111 #define CHECK_MAX(type, TYPE) static_assert(std::is_signed<type>::value ? CHECK_MAX_SIGNED(type, TYPE) : CHECK_MAX_UNSIGNED(type, TYPE), "");
112
113 CHECK_MAX(int8_t, INT8);
114 CHECK_MAX(int16_t, INT16);
115 CHECK_MAX(int32_t, INT32);
116 CHECK_MAX(int64_t, INT64);
117 CHECK_MAX(uint8_t, UINT8);
118 CHECK_MAX(uint16_t, UINT16);
119 CHECK_MAX(uint32_t, UINT32);
120 CHECK_MAX(uint64_t, UINT64);
121
122 CHECK_MAX(int_least8_t, INT_LEAST8);
123 CHECK_MAX(int_least16_t, INT_LEAST16);
124 CHECK_MAX(int_least32_t, INT_LEAST32);
125 CHECK_MAX(int_least64_t, INT_LEAST64);
126 CHECK_MAX(uint_least8_t, UINT_LEAST8);
127 CHECK_MAX(uint_least16_t, UINT_LEAST16);
128 CHECK_MAX(uint_least32_t, UINT_LEAST32);
129 CHECK_MAX(uint_least64_t, UINT_LEAST64);
130
131 CHECK_MAX(int_fast8_t, INT_FAST8);
132 CHECK_MAX(int_fast16_t, INT_FAST16);
133 CHECK_MAX(int_fast32_t, INT_FAST32);
134 CHECK_MAX(int_fast64_t, INT_FAST64);
135 CHECK_MAX(uint_fast8_t, UINT_FAST8);
136 CHECK_MAX(uint_fast16_t, UINT_FAST16);
137 CHECK_MAX(uint_fast32_t, UINT_FAST32);
138 CHECK_MAX(uint_fast64_t, UINT_FAST64);
139
140 CHECK_MAX(intptr_t, INTPTR);
141 CHECK_MAX(uintptr_t, UINTPTR);
142
143 CHECK_MAX(intmax_t, INTMAX);
144 CHECK_MAX(uintmax_t, UINTMAX);
145
146 CHECK_MAX(ptrdiff_t, PTRDIFF);
147 CHECK_MAX(size_t, SIZE);
148 CHECK_MAX(wchar_t, WCHAR);
149
150 CHECK_MAX(sig_atomic_t, SIG_ATOMIC);
151
152 // Check minimums.
153 #define CHECK_MIN_TYPE(type, TYPE) \
154 ((intmax_t)TYPE##_MIN == (INTMAX_MIN >> (CHAR_BIT * (sizeof(intmax_t) - sizeof(type)))))
155
156 #define CHECK_MIN(type, TYPE) static_assert(CHECK_MIN_TYPE(type, TYPE), "")
157
158 CHECK_MIN(int8_t, INT8);
159 CHECK_MIN(int16_t, INT16);
160 CHECK_MIN(int32_t, INT32);
161 CHECK_MIN(int64_t, INT64);
162
163 CHECK_MIN(int_least8_t, INT_LEAST8);
164 CHECK_MIN(int_least16_t, INT_LEAST16);
165 CHECK_MIN(int_least32_t, INT_LEAST32);
166 CHECK_MIN(int_least64_t, INT_LEAST64);
167
168 CHECK_MIN(int_fast8_t, INT_FAST8);
169 CHECK_MIN(int_fast16_t, INT_FAST16);
170 CHECK_MIN(int_fast32_t, INT_FAST32);
171 CHECK_MIN(int_fast64_t, INT_FAST64);
172
173 CHECK_MIN(intptr_t, INTPTR);
174
175 CHECK_MIN(intmax_t, INTMAX);
176
177 CHECK_MIN(ptrdiff_t, PTRDIFF);
178 static_assert(std::is_signed<wchar_t>::value ? CHECK_MIN_TYPE(wchar_t, WCHAR) : (WCHAR_MIN == 0), "");
179
180 static_assert(std::is_signed<sig_atomic_t>::value ? CHECK_MIN_TYPE(sig_atomic_t, SIG_ATOMIC) : (SIG_ATOMIC_MIN == 0), "");
181
182 // The INTN_C and UINTN_C macros expand into integer constants
183 // "corresponding to the type int_leastN_t" and "uint_leastN_t"
184 // respectively.
185
186 static_assert(INT8_C(0) == std::integral_constant<int_least8_t, 0>::value, "");
187 static_assert(INT8_C(-0x7f - 1) == std::integral_constant<int_least8_t, -0x7f - 1>::value, "");
188 static_assert(INT8_C(0x7f) == std::integral_constant<int_least8_t, 0x7f>::value, "");
189
190 static_assert(INT16_C(0) == std::integral_constant<int_least16_t, 0>::value, "");
191 static_assert(INT16_C(-0x7fff - 1) == std::integral_constant<int_least16_t, -0x7fff - 1>::value, "");
192 static_assert(INT16_C(0x7fff) == std::integral_constant<int_least16_t, 0x7fff>::value, "");
193
194 static_assert(INT32_C(0) == std::integral_constant<int_least32_t, 0>::value, "");
195 static_assert(INT32_C(-0x7fffffff - 1) == std::integral_constant<int_least32_t, -0x7fffffff - 1>::value, "");
196 static_assert(INT32_C(0x7fffffff) == std::integral_constant<int_least32_t, 0x7fffffff>::value, "");
197
198 static_assert(INT64_C(0) == std::integral_constant<int_least64_t, 0>::value, "");
199 static_assert(INT64_C(-0x7fffffffffffffff - 1) == std::integral_constant<int_least64_t, -0x7fffffffffffffff - 1>::value, "");
200 static_assert(INT64_C(0x7fffffffffffffff) == std::integral_constant<int_least64_t, 0x7fffffffffffffff>::value, "");
201
202
203 static_assert(UINT8_C(0) == std::integral_constant<uint_least8_t, 0>::value, "");
204 static_assert(UINT8_C(0xff) == std::integral_constant<uint_least8_t, 0xff>::value, "");
205
206 static_assert(UINT16_C(0) == std::integral_constant<uint_least16_t, 0>::value, "");
207 static_assert(UINT16_C(0xffff) == std::integral_constant<uint_least16_t, 0xffff>::value, "");
208
209 static_assert(UINT32_C(0) == std::integral_constant<uint_least32_t, 0>::value, "");
210 static_assert(UINT32_C(0xffffffff) == std::integral_constant<uint_least32_t, 0xffffffff>::value, "");
211
212 static_assert(UINT64_C(0) == std::integral_constant<uint_least64_t, 0>::value, "");
213 static_assert(UINT64_C(0xffffffffffffffff) == std::integral_constant<uint_least64_t, 0xffffffffffffffff>::value, "");
214
215
216 // Unlike the above, the INTMAX_C and UINTMAX_C macros explicitly
217 // produce values of type intmax_t and uintmax_t respectively, not
218 // just compatible values.
219
220 static_assert(std::is_same<intmax_t, decltype(INTMAX_C(0))>::value, "");
221 static_assert(std::is_same<intmax_t, decltype(INTMAX_C(-0x7fffffffffffffff - 1))>::value, "");
222 static_assert(std::is_same<intmax_t, decltype(INTMAX_C(0x7fffffffffffffff))>::value, "");
223 static_assert(INTMAX_C(0) == std::integral_constant<intmax_t, 0>::value, "");
224 static_assert(INTMAX_C(-0xffffffffffffffff - 1) == std::integral_constant<intmax_t, -0xffffffffffffffff - 1>::value, "");
225 static_assert(INTMAX_C(0x7fffffffffffffff) == std::integral_constant<intmax_t, 0x7fffffffffffffff>::value, "");
226
227 static_assert(std::is_same<uintmax_t, decltype(UINTMAX_C(0))>::value, "");
228 static_assert(std::is_same<uintmax_t, decltype(UINTMAX_C(0xffffffffffffffff))>::value, "");
229 static_assert(UINTMAX_C(0) == std::integral_constant<uintmax_t, 0>::value, "");
230 static_assert(UINTMAX_C(0xffffffffffffffff) == std::integral_constant<uintmax_t, 0xffffffffffffffff>::value, "");
231
232
233 // Check PRI* and SCN* format strings.
234 #define LAST(fmt) (fmt[strlen(fmt) - 1])
235
236 // Signed format specifiers.
237 #define CHECK_d(fmt) EXPECT_EQ(LAST(fmt), 'd', "incorrect format specifier")
238 #define CHECK_i(fmt) EXPECT_EQ(LAST(fmt), 'i', "incorrect format specifier")
239
240 // Unsigned format specifiers. Note that X is only used by printf, and
241 // not also by scanf.
242 #define CHECK_o(fmt) EXPECT_EQ(LAST(fmt), 'o', "incorrect format specifier")
243 #define CHECK_u(fmt) EXPECT_EQ(LAST(fmt), 'u', "incorrect format specifier")
244 #define CHECK_x(fmt) EXPECT_EQ(LAST(fmt), 'x', "incorrect format specifier")
245 #define CHECK_X(fmt) EXPECT_EQ(LAST(fmt), 'X', "incorrect format specifier")
246
247 #define CHECK_FORMAT_STRINGS(pri, scn, pcheck, scheck, type, max) do { \
248 pcheck(pri); \
249 scheck(scn); \
250 char buf[256] = {0}; \
251 ASSERT_GT(snprintf(buf, sizeof(buf), "%" pri, (type)max), 1); \
252 type n = (type)0; \
253 ASSERT_EQ(sscanf(buf, "%" scn, &n), 1); \
254 ASSERT_EQ(n, max); \
255 } while (0)
256
257 #define CHECK_SIGNED_FORMATS(size, type, max) do { \
258 CHECK_FORMAT_STRINGS(PRId ## size, SCNd ## size, CHECK_d, CHECK_d, type, max); \
259 CHECK_FORMAT_STRINGS(PRIi ## size, SCNi ## size, CHECK_i, CHECK_i, type, max); \
260 } while (0)
261
262 // Since X is not used by scanf (only x), the last line has PRIX but
263 // SCNx (upper and lower case).
264 #define CHECK_UNSIGNED_FORMATS(size, type, max) do { \
265 CHECK_FORMAT_STRINGS(PRIo ## size, SCNo ## size, CHECK_o, CHECK_o, type, max); \
266 CHECK_FORMAT_STRINGS(PRIu ## size, SCNu ## size, CHECK_u, CHECK_u, type, max); \
267 CHECK_FORMAT_STRINGS(PRIx ## size, SCNx ## size, CHECK_x, CHECK_x, type, max); \
268 CHECK_FORMAT_STRINGS(PRIX ## size, SCNx ## size, CHECK_X, CHECK_x, type, max); \
269 } while (0)
270
271 #define CHECK_FORMATS(size, type, max) do { \
272 if (std::is_signed<type>::value) { \
273 CHECK_SIGNED_FORMATS(size, type, max); \
274 } else { \
275 CHECK_UNSIGNED_FORMATS(size, type, max); \
276 } \
277 } while (0)
278
check_format_specifiers(void)279 static bool check_format_specifiers(void) {
280 BEGIN_TEST;
281
282 CHECK_FORMATS(8, int8_t, INT8_MAX);
283 CHECK_FORMATS(16, int16_t, INT16_MAX);
284 CHECK_FORMATS(32, int32_t, INT32_MAX);
285 CHECK_FORMATS(64, int64_t, INT64_MAX);
286 CHECK_FORMATS(8, uint8_t, UINT8_MAX);
287 CHECK_FORMATS(16, uint16_t, UINT16_MAX);
288 CHECK_FORMATS(32, uint32_t, UINT32_MAX);
289 CHECK_FORMATS(64, uint64_t, UINT64_MAX);
290
291 CHECK_FORMATS(FAST8, int_fast8_t, INT_FAST8_MAX);
292 CHECK_FORMATS(FAST16, int_fast16_t, INT_FAST16_MAX);
293 CHECK_FORMATS(FAST32, int_fast32_t, INT_FAST32_MAX);
294 CHECK_FORMATS(FAST64, int_fast64_t, INT_FAST64_MAX);
295 CHECK_FORMATS(FAST8, uint_fast8_t, UINT_FAST8_MAX);
296 CHECK_FORMATS(FAST16, uint_fast16_t, UINT_FAST16_MAX);
297 CHECK_FORMATS(FAST32, uint_fast32_t, UINT_FAST32_MAX);
298 CHECK_FORMATS(FAST64, uint_fast64_t, UINT_FAST64_MAX);
299
300 CHECK_FORMATS(LEAST8, int_least8_t, INT_LEAST8_MAX);
301 CHECK_FORMATS(LEAST16, int_least16_t, INT_LEAST16_MAX);
302 CHECK_FORMATS(LEAST32, int_least32_t, INT_LEAST32_MAX);
303 CHECK_FORMATS(LEAST64, int_least64_t, INT_LEAST64_MAX);
304 CHECK_FORMATS(LEAST8, uint_least8_t, UINT_LEAST8_MAX);
305 CHECK_FORMATS(LEAST16, uint_least16_t, UINT_LEAST16_MAX);
306 CHECK_FORMATS(LEAST32, uint_least32_t, UINT_LEAST32_MAX);
307 CHECK_FORMATS(LEAST64, uint_least64_t, UINT_LEAST64_MAX);
308
309 CHECK_FORMATS(PTR, intptr_t, INTPTR_MAX);
310 CHECK_FORMATS(PTR, uintptr_t, UINTPTR_MAX);
311
312 // Note that these are definined in addition to %j
313 CHECK_FORMATS(MAX, intmax_t, INTMAX_MAX);
314 CHECK_FORMATS(MAX, uintmax_t, UINTMAX_MAX);
315
316 // ptrdiff_t is simply %t.
317 // size_t is simply %z.
318 // wchar_t is simply %sl.
319
320 // No particular format specifier or macro is defined for sig_atomic_t.
321
322 END_TEST;
323 }
324
325 BEGIN_TEST_CASE(format_specifiers)
RUN_TEST(check_format_specifiers)326 RUN_TEST(check_format_specifiers)
327 END_TEST_CASE(format_specifiers)
328
329 int main(int argc, char** argv) {
330 return unittest_run_all_tests(argc, argv) ? 0 : -1;
331 }
332