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