1/* @title: Compiler Core & Compile-Time Metaprogramming */
2#pragma once
3#include <compiler/name.h>
4#include <stdbool.h>
5#include <stddef.h>
6#include <stdint.h>
7
8/* ==== cc_ Attributes, Markers, and Compiler Directives ==== */
9#define cc_align_as(x) _Alignas(x)
10#define cc_alignof(x) _Alignof(x)
11#define cc_generic(...) _Generic(__VA_ARGS__)
12
13/* clang-format off */
14#define cc_bitfield_barrier(t) t:0
15/* clang-format on */
16
17#define cc_code_init /* Nothing for now, TODO: */
18
19#define cc_noinline __attribute__((noinline))
20#define cc_always_inline __attribute__((always_inline))
21#define cc_noreturn __attribute__((noreturn))
22#define cc_unused __attribute__((unused))
23#define cc_maybe_unused __attribute__((unused))
24#define cc_warn_unused_result __attribute__((warn_unused_result))
25#define cc_nodiscard __attribute__((warn_unused_result))
26#define cc_packed __attribute__((__packed__))
27#define cc_aligned(x) __attribute__((aligned(x)))
28#define cc_cache_aligned __attribute__((aligned(64)))
29#define cc_used __attribute__((used))
30#define cc_section(x) __attribute__((section(x)))
31#define cc_hidden __attribute__((visibility("hidden")))
32#define cc_export __attribute__((visibility("default")))
33#define cc_overloadable __attribute__((overloadable))
34
35#define cc_likely(x) __builtin_expect(!!(x), 1)
36#define cc_unlikely(x) __builtin_expect(!!(x), 0)
37#define cc_unreachable() __builtin_unreachable()
38
39#if defined(cn_id_clang)
40#define cc_assume(expr) __builtin_assume(expr)
41#elif cn_has_attribute(assume)
42#define cc_assume(expr) __attribute__((assume(expr)))
43#else
44#define cc_assume(expr) \
45 do { \
46 if (!(expr)) \
47 __builtin_unreachable(); \
48 } while (0)
49#endif
50
51#define cc_cold __attribute__((cold))
52#define cc_hot __attribute__((hot))
53#define cc_flatten __attribute__((flatten))
54
55#if cn_has_attribute(nodebug)
56#define cc_nodebug __attribute__((nodebug))
57#else
58#define cc_nodebug
59#endif
60
61#define cc_no_asan __attribute__((no_sanitize("address")))
62#define cc_no_ubsan __attribute__((no_sanitize("undefined")))
63#define cc_no_tsan __attribute__((no_sanitize("thread")))
64
65#if defined(cn_id_clang)
66#define cc_no_msan __attribute__((no_sanitize("memory")))
67#define cc_no_csan __attribute__((no_sanitize("coverage")))
68#elif cn_has_attribute(no_sanitize_coverage)
69#define cc_no_msan /* GCC has no MSan */
70#define cc_no_csan __attribute__((no_sanitize_coverage))
71#else
72#define cc_no_msan
73#define cc_no_csan
74#endif
75
76#define cc_no_sanitize(...) __attribute__((no_sanitize(__VA_ARGS__)))
77#define cc_no_stack_protector __attribute__((no_stack_protector))
78#define cc_no_instrument __attribute__((no_instrument_function))
79
80#define cc_deprecated __attribute__((deprecated))
81#define cc_deprecated_msg(msg) __attribute__((deprecated(msg)))
82#define cc_pure __attribute__((pure))
83#define cc_constfn __attribute__((const))
84#define cc_noclone __attribute__((noclone))
85#define cc_malloc_like __attribute__((malloc))
86#define cc_naked __attribute__((naked))
87#define cc_interrupt __attribute__((interrupt))
88#define cc_no_caller_saved_registers __attribute__((no_caller_saved_registers))
89#define cc_returns_nonnull __attribute__((returns_nonnull))
90#define cc_returns_twice __attribute__((returns_twice))
91#define cc_may_alias __attribute__((__may_alias__))
92#define cc_weak __attribute__((weak))
93#define cc_weakref(sym) __attribute__((weakref(#sym)))
94#define cc_alias(sym) __attribute__((alias(#sym)))
95
96#define cc_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
97#define cc_alloc_align(param_idx) __attribute__((alloc_align(param_idx)))
98
99#if defined(cn_id_clang)
100#define cc_nullable _Nullable
101#define cc_nonnull_ptr _Nonnull
102#else
103#define cc_nullable
104#define cc_nonnull_ptr
105#endif
106
107#if cn_id_gcc_at_least(11, 0)
108#define cc_dealloc(fn, arg_idx) __attribute__((malloc(fn, arg_idx)))
109#else
110#define cc_dealloc(fn, arg_idx)
111#endif
112
113#if defined(cn_id_clang)
114#define cc_owner_returns(tag, ...) \
115 __attribute__((ownership_returns(tag, ##__VA_ARGS__)))
116#define cc_owner_takes(tag, arg_idx) \
117 __attribute__((ownership_takes(tag, arg_idx)))
118#else
119#define cc_owner_returns(tag, ...)
120#define cc_owner_takes(tag, arg_idx)
121#endif
122
123#if defined(cn_id_clang)
124#define cc_analyzer_noreturn __attribute__((analyzer_noreturn))
125#else
126#define cc_analyzer_noreturn
127#endif
128
129#define cc_error(msg) __attribute__((error(msg)))
130#define cc_warning(msg) __attribute__((warning(msg)))
131#define cc_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
132
133/* Bounds for a flexible array or pointer member */
134#if defined(cn_id_clang) || cn_id_gcc_at_least(16, 0)
135#define cc_counted_by(member) __attribute__((counted_by(member)))
136#else
137#define cc_counted_by(member)
138#endif
139
140#if cn_has_attribute(counted_by_or_null)
141#define cc_counted_by_or_null(member) \
142 __attribute__((counted_by_or_null(member)))
143#else
144#define cc_counted_by_or_null(member)
145#endif
146
147#if cn_has_attribute(sized_by)
148#define cc_sized_by(member) __attribute__((sized_by(member)))
149#else
150#define cc_sized_by(member)
151#endif
152
153#if cn_has_attribute(sized_by_or_null)
154#define cc_sized_by_or_null(member) __attribute__((sized_by_or_null(member)))
155#else
156#define cc_sized_by_or_null(member)
157#endif
158
159/*
160 * void fill(void *p cc_pass_object_size(0), size_t n)
161 * cc_diagnose_if(n > __builtin_object_size(p, 0), "overflow", "error");
162 */
163#if cn_has_attribute(pass_object_size)
164#define cc_pass_object_size(type) __attribute__((pass_object_size(type)))
165#else
166#define cc_pass_object_size(type)
167#endif
168
169#if cn_has_attribute(diagnose_if)
170#define cc_diagnose_if(cond, msg, severity) \
171 __attribute__((diagnose_if(cond, msg, severity)))
172#else
173#define cc_diagnose_if(cond, msg, severity)
174#endif
175
176/*
177 * void take(void *p, unsigned flags, size_t n)
178 * ct_precond(p != NULL)
179 * ct_precond(flags & F_A, "use take_noflag() when F_A is clear")
180 * ct_precond(n <= 4096);
181 *
182 * Notably only is able to check constants passed in.
183 * enforce_precond() for runtime precondition validation
184 */
185#define ct_precond(...) \
186 PP_CONCAT(_ct_precond_, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
187#define _ct_precond_1(cond) \
188 cc_diagnose_if(!(cond), "precondition violated: " #cond, "error")
189#define _ct_precond_2(cond, hint) \
190 cc_diagnose_if(!(cond), "precondition violated: " #cond " -- " hint, \
191 "error")
192
193#if cn_has_attribute(enable_if)
194#define cc_enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
195#else
196#define cc_enable_if(cond, msg)
197#endif
198
199#if defined(cn_id_gcc)
200#define cc_access(mode, ...) __attribute__((access(mode, __VA_ARGS__)))
201#else
202#define cc_access(mode, ...)
203#endif
204
205#define cc_printf_like(fmt_idx, arg_idx) \
206 __attribute__((format(printf, fmt_idx, arg_idx)))
207#define cc_constructor(prio) __attribute__((constructor(prio)))
208#define cc_destructor(prio) __attribute__((destructor(prio)))
209#define cc_fallthrough __attribute__((fallthrough))
210#define cc_cleanup(fn) __attribute__((cleanup(fn)))
211#define cc_target(...) __attribute__((target(__VA_ARGS__)))
212#define cc_optimize(...) __attribute__((optimize(__VA_ARGS__)))
213#define cc_designated_init __attribute__((designated_init))
214
215#if cn_has_attribute(uninitialized)
216#define cc_uninitialized __attribute__((uninitialized))
217#else
218#define cc_uninitialized
219#endif
220
221#if cn_has_attribute(nonstring)
222#define cc_nonstring __attribute__((nonstring))
223#else
224#define cc_nonstring
225#endif
226
227#if defined(cn_id_gcc) || defined(cn_id_clang)
228#define cc_restrict __restrict__
229#else
230#define cc_restrict
231#endif
232
233#if defined(cn_id_clang)
234#define cc_mem(n) __attribute__((address_space(n)))
235#else
236#define cc_mem(n)
237#endif
238
239#define cc_mem_io cc_mem(1)
240
241#if defined(cn_id_clang)
242#define cc_mem_rcu __attribute__((address_space(2), noderef))
243#else
244#define cc_mem_rcu
245#endif
246
247#if defined(cn_id_clang)
248#define cc_mem_any_fn __attribute__((address_space(3), noderef))
249#else
250#define cc_mem_any_fn
251#endif
252
253/* ==== Preprocessor Metaprogramming ==== */
254
255#define PP_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, \
256 _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, \
257 _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, \
258 _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
259 _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, \
260 _63, _64, N, ...) \
261 N
262
263#define PP_RSEQ_N() \
264 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, \
265 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, \
266 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, \
267 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
268
269#define PP_NARG_HELPER(...) PP_ARG_N(__VA_ARGS__)
270#define PP_NARG(...) PP_NARG_HELPER(_, ##__VA_ARGS__, PP_RSEQ_N())
271
272#define PP_DISPATCH_(name, n) name##_##n
273#define PP_DISPATCH(name, n) PP_DISPATCH_(name, n)
274
275#define PP_OVERLOAD(name, ...) PP_DISPATCH(name, PP_NARG(__VA_ARGS__))
276#define PP_CALL(name, ...) PP_OVERLOAD(name, __VA_ARGS__)(__VA_ARGS__)
277
278/* The 2 and 3 variants are used when a PP_CALL wants to expand
279 * a PP_CALL (first layer), and when a PP_CALL2 wants to expand
280 * a PP_CALL or PP_CALL2 (second layer). If anyone wants another
281 * layer, they should probably restructure their code */
282#define PP_OVERLOAD2(name, ...) PP_DISPATCH(name, PP_NARG(__VA_ARGS__))
283#define PP_CALL2(name, ...) PP_OVERLOAD2(name, __VA_ARGS__)(__VA_ARGS__)
284
285#define PP_OVERLOAD3(name, ...) PP_DISPATCH(name, PP_NARG(__VA_ARGS__))
286#define PP_CALL3(name, ...) PP_OVERLOAD3(name, __VA_ARGS__)(__VA_ARGS__)
287
288#define PP_CONCAT_(a, b) a##b
289#define PP_CONCAT(a, b) PP_CONCAT_(a, b)
290
291#define PP_STRINGIZE_(x) #x
292#define PP_STRINGIZE(x) PP_STRINGIZE_(x)
293
294#define PP_EXPAND(...) __VA_ARGS__
295
296#define PP_GET_1(a, ...) a
297#define PP_GET_2(a, b, ...) b
298#define PP_GET_3(a, b, c, ...) c
299#define PP_GET_4(a, b, c, d, ...) d
300#define PP_GET_5(a, b, c, d, e, ...) e
301
302#define PP_ARG(n, ...) PP_CONCAT(PP_GET_, n)(__VA_ARGS__)
303
304#define PP_DROP_1(a, ...) __VA_ARGS__
305#define PP_DROP_2(a, b, ...) __VA_ARGS__
306#define PP_DROP_3(a, b, c, ...) __VA_ARGS__
307#define PP_DROP_4(a, b, c, d, ...) __VA_ARGS__
308#define PP_DROP_5(a, b, c, d, e, ...) __VA_ARGS__
309
310#define PP_VA_ARGS_AFTER(n, ...) PP_CONCAT(PP_DROP_, n)(__VA_ARGS__)
311
312/* Unused argument discarders */
313#define PP_CC_VAR_UNUSED_1(a) ((void) (a))
314#define PP_CC_VAR_UNUSED_2(a, b) (PP_CC_VAR_UNUSED_1(a), (void) (b))
315#define PP_CC_VAR_UNUSED_3(a, b, c) (PP_CC_VAR_UNUSED_2(a, b), (void) (c))
316#define PP_CC_VAR_UNUSED_4(a, b, c, d) (PP_CC_VAR_UNUSED_3(a, b, c), (void) (d))
317#define PP_CC_VAR_UNUSED_5(a, b, c, d, e) \
318 (PP_CC_VAR_UNUSED_4(a, b, c, d), (void) (e))
319#define PP_CC_VAR_UNUSED_6(a, b, c, d, e, f) \
320 (PP_CC_VAR_UNUSED_5(a, b, c, d, e), (void) (f))
321#define PP_CC_VAR_UNUSED_7(a, b, c, d, e, f, g) \
322 (PP_CC_VAR_UNUSED_6(a, b, c, d, e, f), (void) (g))
323#define PP_CC_VAR_UNUSED_8(a, b, c, d, e, f, g, h) \
324 (PP_CC_VAR_UNUSED_7(a, b, c, d, e, f, g), (void) (h))
325
326#define PP_UNPAREN(x) PP_UNPAREN_ESC_(PP_UNPAREN_ISH_ x)
327#define PP_UNPAREN_ISH_(...) PP_UNPAREN_ISH_ __VA_ARGS__
328#define PP_UNPAREN_ESC_(...) PP_UNPAREN_ESC__(__VA_ARGS__)
329#define PP_UNPAREN_ESC__(...) PP_UNPAREN_VAN_##__VA_ARGS__
330#define PP_UNPAREN_VAN_PP_UNPAREN_ISH_
331
332/* 1 if x is parenthesized, else 0 */
333#define PP_IS_PAREN(x) PP_IS_PAREN_N_(PP_IS_PAREN_PROBE_ x, 0, ~)
334#define PP_IS_PAREN_PROBE_(...) ~, 1,
335#define PP_IS_PAREN_N_(...) PP_IS_PAREN_PICK_(__VA_ARGS__)
336#define PP_IS_PAREN_PICK_(x, n, ...) n
337
338/* PP_IIF(0 or 1)(then, else) */
339#define PP_IIF(c) PP_CONCAT(PP_IIF_, c)
340#define PP_IIF_0(t, f) f
341#define PP_IIF_1(t, f) t
342
343#define PP_FOREACH_CTX(m, c, ...) \
344 PP_CONCAT(PP_FE_, PP_NARG(__VA_ARGS__))(m, c, __VA_ARGS__)
345#define PP_FE_0(m, c, ...)
346#define PP_FE_1(m, c, x) m(c, x)
347#define PP_FE_2(m, c, x, ...) m(c, x) PP_FE_1(m, c, __VA_ARGS__)
348#define PP_FE_3(m, c, x, ...) m(c, x) PP_FE_2(m, c, __VA_ARGS__)
349#define PP_FE_4(m, c, x, ...) m(c, x) PP_FE_3(m, c, __VA_ARGS__)
350#define PP_FE_5(m, c, x, ...) m(c, x) PP_FE_4(m, c, __VA_ARGS__)
351#define PP_FE_6(m, c, x, ...) m(c, x) PP_FE_5(m, c, __VA_ARGS__)
352#define PP_FE_7(m, c, x, ...) m(c, x) PP_FE_6(m, c, __VA_ARGS__)
353#define PP_FE_8(m, c, x, ...) m(c, x) PP_FE_7(m, c, __VA_ARGS__)
354#define PP_FE_9(m, c, x, ...) m(c, x) PP_FE_8(m, c, __VA_ARGS__)
355#define PP_FE_10(m, c, x, ...) m(c, x) PP_FE_9(m, c, __VA_ARGS__)
356#define PP_FE_11(m, c, x, ...) m(c, x) PP_FE_10(m, c, __VA_ARGS__)
357#define PP_FE_12(m, c, x, ...) m(c, x) PP_FE_11(m, c, __VA_ARGS__)
358#define PP_FE_13(m, c, x, ...) m(c, x) PP_FE_12(m, c, __VA_ARGS__)
359#define PP_FE_14(m, c, x, ...) m(c, x) PP_FE_13(m, c, __VA_ARGS__)
360#define PP_FE_15(m, c, x, ...) m(c, x) PP_FE_14(m, c, __VA_ARGS__)
361#define PP_FE_16(m, c, x, ...) m(c, x) PP_FE_15(m, c, __VA_ARGS__)
362#define PP_FE_17(m, c, x, ...) m(c, x) PP_FE_16(m, c, __VA_ARGS__)
363#define PP_FE_18(m, c, x, ...) m(c, x) PP_FE_17(m, c, __VA_ARGS__)
364#define PP_FE_19(m, c, x, ...) m(c, x) PP_FE_18(m, c, __VA_ARGS__)
365#define PP_FE_20(m, c, x, ...) m(c, x) PP_FE_19(m, c, __VA_ARGS__)
366#define PP_FE_21(m, c, x, ...) m(c, x) PP_FE_20(m, c, __VA_ARGS__)
367#define PP_FE_22(m, c, x, ...) m(c, x) PP_FE_21(m, c, __VA_ARGS__)
368#define PP_FE_23(m, c, x, ...) m(c, x) PP_FE_22(m, c, __VA_ARGS__)
369#define PP_FE_24(m, c, x, ...) m(c, x) PP_FE_23(m, c, __VA_ARGS__)
370#define PP_FE_25(m, c, x, ...) m(c, x) PP_FE_24(m, c, __VA_ARGS__)
371#define PP_FE_26(m, c, x, ...) m(c, x) PP_FE_25(m, c, __VA_ARGS__)
372#define PP_FE_27(m, c, x, ...) m(c, x) PP_FE_26(m, c, __VA_ARGS__)
373#define PP_FE_28(m, c, x, ...) m(c, x) PP_FE_27(m, c, __VA_ARGS__)
374#define PP_FE_29(m, c, x, ...) m(c, x) PP_FE_28(m, c, __VA_ARGS__)
375#define PP_FE_30(m, c, x, ...) m(c, x) PP_FE_29(m, c, __VA_ARGS__)
376#define PP_FE_31(m, c, x, ...) m(c, x) PP_FE_30(m, c, __VA_ARGS__)
377#define PP_FE_32(m, c, x, ...) m(c, x) PP_FE_31(m, c, __VA_ARGS__)
378
379#define cc_ignore(...) PP_CALL(PP_CC_VAR_UNUSED, __VA_ARGS__)
380
381#define cc_discard(expr) \
382 ({ \
383 __auto_type _cc_discard_ = (expr); \
384 (void) _cc_discard_; \
385 })
386
387/* ==== ct_ Compile-Time & Static Assertions ==== */
388
389#define static_assert_1(cond) _Static_assert(cond, #cond)
390#define static_assert_2(cond, msg) _Static_assert(cond, msg)
391
392#define static_assert(...) PP_CALL2(static_assert, __VA_ARGS__)
393
394#define ct_assert_size(type, size) \
395 static_assert(sizeof(type) == (size), "sizeof(" #type ") != " #size)
396
397#define ct_assert_align(type, align) \
398 static_assert(cc_alignof(type) == (align), "alignof(" #type ") " \
399 "!= " #align)
400
401#define ct_assert_offset(type, member, offset) \
402 static_assert(__builtin_offsetof(type, member) == (offset), \
403 "offsetof(" #type ", " #member ") != " #offset)
404
405#define ct_assert_same_size(type_a, type_b) \
406 static_assert(sizeof(type_a) == sizeof(type_b), \
407 "sizeof(" #type_a ") != sizeof(" #type_b ")")
408
409#define ct_assert_struct_size_eq(struct_, want_) \
410 ct_assert_size(struct struct_, want_)
411
412#define ct_assert_struct_align_eq(struct_, want_) \
413 ct_assert_align(struct struct_, want_)
414
415#define ct_assert_union_size_eq(union_, want_) \
416 ct_assert_size(union union_, want_)
417
418#define ct_assert_union_align_eq(union_, want_) \
419 ct_assert_align(union union_, want_)
420
421#define ct_assert_power_of_two(n) \
422 static_assert(((n) > 0 && (((n) & ((n) - 1)) == 0)), \
423 #n " is not a power of two")
424
425#define ct_assert_nonempty_str(s) \
426 static_assert(sizeof(s) > 1, "empty string: " #s)
427
428#define ct_strong_int(stem, STEM, base, max_) \
429 typedef enum : base { \
430 STEM##_ZERO = 0, \
431 STEM##_MIN = 0, \
432 STEM##_MAX = (max_), \
433 } stem##_t
434
435#define ct_expr_assert_zero(cond, msg) \
436 (sizeof(struct { \
437 _Static_assert(__builtin_choose_expr((cond), 1, 0), msg); \
438 char __ct_pad; \
439 }) * \
440 0)
441
442#define ct_expr_assert(cond, msg) ((void) ct_expr_assert_zero(cond, msg))
443
444/* === ct_ Compile-Time Type System & Reflection ==== */
445
446#define ct_is_const(x) __builtin_constant_p(x)
447
448#define ct_is_ice(x) \
449 (sizeof(int) == sizeof(*(8 ? ((void *) ((long) (x) * 0l)) : (int *) 8)))
450
451#define ct_raw(x) ((typeof((x) + 0)) (x))
452
453#define ct_same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
454#define ct_is_type(T, x) __builtin_types_compatible_p(T, typeof(x))
455
456#define ct_is_array(a) \
457 (!__builtin_types_compatible_p(typeof(a), typeof(&(a)[0])))
458
459#define ct_array_size(a) \
460 (ct_expr_assert_zero(ct_is_array(a), "`" #a "` is a pointer, not an " \
461 "array; ct_array_size() needs a " \
462 "real array") + \
463 (sizeof(a) / sizeof((a)[0])))
464
465#define ct_const_min(a, b) __builtin_choose_expr((a) < (b), (a), (b))
466#define ct_const_max(a, b) __builtin_choose_expr((a) > (b), (a), (b))
467#define ct_const_clamp(val, min, max) ct_const_min(ct_const_max(val, min), max)
468
469#define ct_decay(x) typeof(0 ? (x) : ((void) ++(int) {0}, (x)))
470#define ct_is_str(x) \
471 (__builtin_types_compatible_p(ct_decay(x), char *) || \
472 __builtin_types_compatible_p(ct_decay(x), const char *))
473
474#define ct_as_str(x) ((const char *) (uintptr_t) (x))
475#define ct_as_type(T, x) ((T) (uintptr_t) (x))
476
477#define ct_bitsizeof(x) (sizeof(x) * __CHAR_BIT__)
478#define ct_type_bitsize(T) (sizeof(T) * __CHAR_BIT__)
479
480#define ct_field_sizeof(type, member) sizeof(((type *) 0)->member)
481#define ct_field_offset(type, member) __builtin_offsetof(type, member)
482
483#define ct_is_pointer(x) (__builtin_classify_type(x) == 5)
484#define ct_is_fn_ptr(x) \
485 __builtin_types_compatible_p(typeof(&*(x)), typeof(&**(x)))
486#define ct_is_integral(x) \
487 (__builtin_classify_type(x) == 1 && \
488 !__builtin_types_compatible_p(typeof(x), bool))
489#define ct_is_bool(x) __builtin_types_compatible_p(typeof(x), _Bool)
490#define ct_is_struct(x) (__builtin_classify_type(x) == 12)
491#define ct_is_union(x) (__builtin_classify_type(x) == 13)
492
493#define ct_is_power_of_two(n) ((n) > 0 && (((n) & ((n) - 1)) == 0))
494
495#define ct_type_is_signed(x) ((typeof(x)) -1 < (typeof(x)) 1)
496
497#define ct_min_val(T) \
498 ((T) (ct_type_is_signed(T) \
499 ? (T) ((__UINTMAX_TYPE__) 1 << (ct_type_bitsize(T) - 1)) \
500 : (T) 0))
501
502#define ct_max_val(T) \
503 ((T) (ct_type_is_signed(T) \
504 ? (T) (((__UINTMAX_TYPE__) 1 << (ct_type_bitsize(T) - 1)) - 1) \
505 : (T) ~(T) 0))
506
507/* Require expr to have the requested type, does not evaluate x */
508#define ct_typecheck(type, x) \
509 ct_expr_assert(__builtin_types_compatible_p(type, typeof(x)), \
510 "`" #x "` must have type `" #type "`")
511
512#define ct_typecheck_same(x, y) \
513 ct_expr_assert(__builtin_types_compatible_p(typeof(x), typeof(y)), \
514 "`" #x "` and `" #y "` must have the same type")
515
516#define ct_typecheck_same_unqual(x, y) \
517 ct_expr_assert(__builtin_types_compatible_p(__typeof_unqual__(x), \
518 __typeof_unqual__(y)), \
519 "`" #x "` and `" #y "` must have the same type")
520
521#define ct_typecheck_integer_as(x, name) \
522 ct_expr_assert(ct_is_integral(x), "`" #name "` must have an integer " \
523 "type ")
524#define ct_typecheck_integer(x) ct_typecheck_integer_as(x, x)
525
526/* Require x to have a signed integer or enum type */
527#define ct_typecheck_signed_as(x, name) \
528 (ct_typecheck_integer_as(x, name), \
529 ct_expr_assert(ct_type_is_signed(x), \
530 "`" #name "` must have a signed integer type"))
531#define ct_typecheck_signed(x) ct_typecheck_signed_as(x, x)
532
533/* Require x to have an unsigned integer or enum type */
534#define ct_typecheck_unsigned_as(x, name) \
535 (ct_typecheck_integer_as(x, name), \
536 ct_expr_assert(!ct_type_is_signed(x), \
537 "`" #name "` must have an unsigned integer type"))
538#define ct_typecheck_unsigned(x) ct_typecheck_unsigned_as(x, x)
539
540#define ct_typecheck_intmax_nonnegative(x) \
541 (((__UINTMAX_TYPE__) (__INTMAX_TYPE__) (x) >> \
542 (sizeof(__INTMAX_TYPE__) * __CHAR_BIT__ - 1)) == 0)
543
544#define ct_typecheck_source_nonnegative(to, from) \
545 (!(ct_type_is_signed(from) && !ct_type_is_signed(to)) || \
546 ct_typecheck_intmax_nonnegative(from))
547
548#define ct_typecheck_converted_nonnegative(to, from) \
549 (!(!ct_type_is_signed(from) && ct_type_is_signed(to)) || \
550 ct_typecheck_intmax_nonnegative((typeof(to)) (from)))
551
552#define ct_typecheck_value_fits(to, from) \
553 (ct_typecheck_source_nonnegative(to, from) && \
554 ct_typecheck_converted_nonnegative(to, from) && \
555 (typeof(from)) ((typeof(to)) (from)) == (typeof(from)) (from))
556
557/* Whole type widening from signedness and width,
558 * always an integer constant expr */
559#define ct_typecheck_structurally_widenable(to, from) \
560 (((ct_type_is_signed(to) == ct_type_is_signed(from)) && \
561 sizeof(typeof(from)) <= sizeof(typeof(to))) || \
562 (ct_type_is_signed(to) && !ct_type_is_signed(from) && \
563 sizeof(typeof(from)) < sizeof(typeof(to))))
564
565#define ct_widenable_ok(to, from) \
566 __builtin_choose_expr(ct_is_ice(from), \
567 (ct_typecheck_structurally_widenable(to, from)) || \
568 (ct_typecheck_value_fits(to, from)), \
569 (ct_typecheck_structurally_widenable(to, from)))
570
571/* Require every value of source to be representable by destination,
572 * or source to be a constant whose value is representable by
573 * the destination. Equal widths require equal signedness, and unsigned
574 * sources require wider signed destinations */
575#define ct_typecheck_widenable_to(destination, source) \
576 (ct_typecheck_integer(destination), ct_typecheck_integer(source), \
577 ct_expr_assert(ct_widenable_ok(destination, source), \
578 "`" #source "` cannot be converted to the destination " \
579 "type without changing its value. cast it explicitly"))
580
581/* Common/larger type to cast up to */
582#define ct_common_type_2(a, b) \
583 typeof(__builtin_choose_expr(sizeof(typeof(a)) >= sizeof(typeof(b)), (a), \
584 (b)))
585