commit d51c0ff8fbdc514827366d5bed17e1352c39cbb5
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 7 May 2026 08:49:40 -0700
cfree freestanding headers
Diffstat:
11 files changed, 596 insertions(+), 0 deletions(-)
diff --git a/builtins.md b/builtins.md
@@ -0,0 +1,135 @@
+# Compiler builtins used by cfree
+
+Every value in cfree's freestanding headers is delegated to the compiler.
+This file lists what we rely on, grouped by header. All names below are
+provided by both GCC (≥ 4.x) and Clang. They are predefined macros unless
+marked **(builtin)**, in which case they are intrinsic identifiers usable
+in expressions.
+
+---
+
+## `<float.h>`
+
+Mostly a 1-to-1 passthrough of `__*__` macros to their C11 spellings.
+
+| C11 macro | Compiler source |
+| ------------------ | ------------------------------------- |
+| `FLT_ROUNDS` | `__builtin_flt_rounds()` **(builtin)** — runtime rounding mode |
+| `FLT_EVAL_METHOD` | `__FLT_EVAL_METHOD__` |
+| `FLT_RADIX` | `__FLT_RADIX__` |
+| `*_HAS_SUBNORM` | `__{FLT,DBL,LDBL}_HAS_DENORM__` |
+| `*_MANT_DIG` | `__{FLT,DBL,LDBL}_MANT_DIG__` |
+| `*_DECIMAL_DIG` | `__{FLT,DBL,LDBL}_DECIMAL_DIG__` |
+| `DECIMAL_DIG` | `__DECIMAL_DIG__` |
+| `*_DIG` | `__{FLT,DBL,LDBL}_DIG__` |
+| `*_MIN_EXP` | `__{FLT,DBL,LDBL}_MIN_EXP__` |
+| `*_MIN_10_EXP` | `__{FLT,DBL,LDBL}_MIN_10_EXP__` |
+| `*_MAX_EXP` | `__{FLT,DBL,LDBL}_MAX_EXP__` |
+| `*_MAX_10_EXP` | `__{FLT,DBL,LDBL}_MAX_10_EXP__` |
+| `*_MAX` | `__{FLT,DBL,LDBL}_MAX__` |
+| `*_EPSILON` | `__{FLT,DBL,LDBL}_EPSILON__` |
+| `*_MIN` | `__{FLT,DBL,LDBL}_MIN__` |
+| `*_TRUE_MIN` | `__{FLT,DBL,LDBL}_DENORM_MIN__` |
+
+Note the rename: C11 uses `SUBNORM`/`TRUE_MIN`; GCC/Clang use `DENORM`/`DENORM_MIN`.
+
+---
+
+## `<limits.h>`
+
+| C11 macro | Compiler source |
+| ------------ | --------------------------------------------------------- |
+| `CHAR_BIT` | `__CHAR_BIT__` |
+| `SCHAR_MAX` | `__SCHAR_MAX__` |
+| `CHAR_*` | derived from `__CHAR_UNSIGNED__` (defined ⇒ char is unsigned) |
+| `SHRT_MAX` | `__SHRT_MAX__` |
+| `INT_MAX` | `__INT_MAX__` |
+| `LONG_MAX` | `__LONG_MAX__` |
+| `LLONG_MAX` | `__LONG_LONG_MAX__` |
+
+`*_MIN` / unsigned `*_MAX` are derived arithmetically from the signed `*_MAX`
+(C11 guarantees two's-complement-or-equivalent representations make this
+exact). `MB_LEN_MAX` is *not* compiler-provided — we hardcode `1`.
+
+---
+
+## `<stddef.h>`
+
+| C11 name | Compiler source |
+| ------------ | ------------------------------------- |
+| `ptrdiff_t` | `__PTRDIFF_TYPE__` |
+| `size_t` | `__SIZE_TYPE__` |
+| `wchar_t` | `__WCHAR_TYPE__` (C only; keyword in C++) |
+| `offsetof` | `__builtin_offsetof(t, m)` **(builtin)** |
+| `NULL` | `((void*)0)` — not compiler-provided |
+| `max_align_t`| no builtin — a struct of `long long` + `long double` is the conventional definition |
+
+---
+
+## `<stdint.h>`
+
+For each width N ∈ {8, 16, 32, 64} the compiler provides a *type*, a *max*,
+and a *constant-suffix* macro. We pass them through unchanged.
+
+### Types
+- `__INT{N}_TYPE__`, `__UINT{N}_TYPE__`
+- `__INT_LEAST{N}_TYPE__`, `__UINT_LEAST{N}_TYPE__`
+- `__INT_FAST{N}_TYPE__`, `__UINT_FAST{N}_TYPE__`
+- `__INTPTR_TYPE__`, `__UINTPTR_TYPE__`
+- `__INTMAX_TYPE__`, `__UINTMAX_TYPE__`
+
+### Limits
+- `__INT{N}_MAX__`, `__UINT{N}_MAX__`
+- `__INT_LEAST{N}_MAX__`, `__UINT_LEAST{N}_MAX__`
+- `__INT_FAST{N}_MAX__`, `__UINT_FAST{N}_MAX__`
+- `__INTPTR_MAX__`, `__UINTPTR_MAX__`
+- `__INTMAX_MAX__`, `__UINTMAX_MAX__`
+- `__PTRDIFF_MAX__`, `__SIZE_MAX__`
+- `__WCHAR_MAX__`, `__WCHAR_MIN__`
+- `__WINT_MAX__`, `__WINT_MIN__`
+- `__SIG_ATOMIC_MAX__`, `__SIG_ATOMIC_MIN__`
+
+`*_MIN` for signed types is derived as `(-MAX - 1)`.
+
+### Constant macros (function-like)
+- `__INT{N}_C(c)`, `__UINT{N}_C(c)` — append the literal suffix appropriate
+ for the corresponding `int_least{N}_t` (e.g. `__INT64_C(1)` → `1L` or `1LL`
+ depending on target).
+- `__INTMAX_C(c)`, `__UINTMAX_C(c)` — same for `intmax_t`.
+
+---
+
+## `<stdarg.h>`
+
+Entirely compiler-supplied — varargs ABI is too target-specific to express
+in portable C.
+
+| C11 name | Builtin |
+| ---------- | ----------------------------- |
+| `va_list` | `__builtin_va_list` (type) |
+| `va_start` | `__builtin_va_start(ap, last)`|
+| `va_arg` | `__builtin_va_arg(ap, type)` |
+| `va_end` | `__builtin_va_end(ap)` |
+| `va_copy` | `__builtin_va_copy(dst, src)` |
+
+---
+
+## `<stdalign.h>`, `<stdbool.h>`, `<stdnoreturn.h>`, `<iso646.h>`
+
+No builtins. These headers are pure preprocessor aliases for C11 keywords
+(`_Alignas`, `_Alignof`, `_Bool`, `_Noreturn`) and operator spellings.
+
+---
+
+## Discovery
+
+To enumerate every macro a particular compiler predefines on the current
+target:
+
+```sh
+cc -dM -E -x c /dev/null | sort
+```
+
+The full set is target- and version-dependent; the macros above are the
+ones cfree relies on, and all are present on every GCC/Clang target we
+target.
diff --git a/include/float.h b/include/float.h
@@ -0,0 +1,76 @@
+/* float.h -- C11 7.7 -- Characteristics of floating types */
+#ifndef CFREE_FLOAT_H
+#define CFREE_FLOAT_H
+
+/* Rounding mode, FLT_EVAL_METHOD, and the radix are target-/runtime-dependent
+ and predefined by the compiler. */
+#define FLT_ROUNDS (__builtin_flt_rounds())
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#define FLT_RADIX __FLT_RADIX__
+
+/* Subnormal support (C11 added). 1 = supports subnormals, 0 = does not,
+ -1 = indeterminable. */
+#define FLT_HAS_SUBNORM __FLT_HAS_DENORM__
+#define DBL_HAS_SUBNORM __DBL_HAS_DENORM__
+#define LDBL_HAS_SUBNORM __LDBL_HAS_DENORM__
+
+/* Number of base-FLT_RADIX mantissa digits. */
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+/* Number of decimal digits, n, such that any floating value with p radix-b
+ digits can be rounded into a decimal with n digits and back without loss. */
+#define FLT_DECIMAL_DIG __FLT_DECIMAL_DIG__
+#define DBL_DECIMAL_DIG __DBL_DECIMAL_DIG__
+#define LDBL_DECIMAL_DIG __LDBL_DECIMAL_DIG__
+#define DECIMAL_DIG __DECIMAL_DIG__
+
+/* Number of decimal digits q such that any number with q decimals can be
+ rounded into the type and back unchanged. */
+#define FLT_DIG __FLT_DIG__
+#define DBL_DIG __DBL_DIG__
+#define LDBL_DIG __LDBL_DIG__
+
+/* Minimum negative integer e such that FLT_RADIX**(e-1) is a normalized
+ value. */
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+/* Minimum negative integer such that 10 raised to it is a normalized value. */
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+/* Maximum integer e such that FLT_RADIX**(e-1) is representable. */
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+/* Maximum integer such that 10 raised to it is representable. */
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+/* Maximum representable finite value. */
+#define FLT_MAX __FLT_MAX__
+#define DBL_MAX __DBL_MAX__
+#define LDBL_MAX __LDBL_MAX__
+
+/* Difference between 1 and the least value greater than 1. */
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+/* Minimum normalized positive value. */
+#define FLT_MIN __FLT_MIN__
+#define DBL_MIN __DBL_MIN__
+#define LDBL_MIN __LDBL_MIN__
+
+/* Minimum positive value (may be subnormal). C11 added. */
+#define FLT_TRUE_MIN __FLT_DENORM_MIN__
+#define DBL_TRUE_MIN __DBL_DENORM_MIN__
+#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
+
+#endif
diff --git a/include/iso646.h b/include/iso646.h
@@ -0,0 +1,17 @@
+/* iso646.h -- C11 7.9 -- Alternative spellings */
+#ifndef CFREE_ISO646_H
+#define CFREE_ISO646_H
+
+#define and &&
+#define and_eq &=
+#define bitand &
+#define bitor |
+#define compl ~
+#define not !
+#define not_eq !=
+#define or ||
+#define or_eq |=
+#define xor ^
+#define xor_eq ^=
+
+#endif
diff --git a/include/limits.h b/include/limits.h
@@ -0,0 +1,50 @@
+/* limits.h -- C11 7.10 -- Sizes of integer types */
+#ifndef CFREE_LIMITS_H
+#define CFREE_LIMITS_H
+
+/* Number of bits in a byte. C11 mandates value >= 8; on every supported
+ GCC/Clang target this is 8. */
+#define CHAR_BIT __CHAR_BIT__
+
+/* Maximum length of a multibyte character. C11 requires this to be >= 1.
+ The value depends on the locale; freestanding code has no locale facility,
+ so 1 is the safest portable answer. (Compilers do not predefine this.) */
+#define MB_LEN_MAX 1
+
+/* signed char */
+#define SCHAR_MAX __SCHAR_MAX__
+#define SCHAR_MIN (-SCHAR_MAX - 1)
+
+/* unsigned char */
+#define UCHAR_MAX (SCHAR_MAX * 2 + 1)
+
+/* plain char -- signedness is implementation-defined */
+#ifdef __CHAR_UNSIGNED__
+# define CHAR_MIN 0
+# define CHAR_MAX UCHAR_MAX
+#else
+# define CHAR_MIN SCHAR_MIN
+# define CHAR_MAX SCHAR_MAX
+#endif
+
+/* short */
+#define SHRT_MAX __SHRT_MAX__
+#define SHRT_MIN (-SHRT_MAX - 1)
+#define USHRT_MAX (SHRT_MAX * 2 + 1)
+
+/* int */
+#define INT_MAX __INT_MAX__
+#define INT_MIN (-INT_MAX - 1)
+#define UINT_MAX (INT_MAX * 2U + 1U)
+
+/* long */
+#define LONG_MAX __LONG_MAX__
+#define LONG_MIN (-LONG_MAX - 1L)
+#define ULONG_MAX (LONG_MAX * 2UL + 1UL)
+
+/* long long */
+#define LLONG_MAX __LONG_LONG_MAX__
+#define LLONG_MIN (-LLONG_MAX - 1LL)
+#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+
+#endif
diff --git a/include/stdalign.h b/include/stdalign.h
@@ -0,0 +1,11 @@
+/* stdalign.h -- C11 7.15 -- Alignment */
+#ifndef CFREE_STDALIGN_H
+#define CFREE_STDALIGN_H
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif
diff --git a/include/stdarg.h b/include/stdarg.h
@@ -0,0 +1,15 @@
+/* stdarg.h -- C11 7.16 -- Variable arguments */
+#ifndef CFREE_STDARG_H
+#define CFREE_STDARG_H
+
+typedef __builtin_va_list va_list;
+
+#define va_start(ap, last) __builtin_va_start(ap, last)
+#define va_arg(ap, type) __builtin_va_arg(ap, type)
+#define va_end(ap) __builtin_va_end(ap)
+#define va_copy(dst, src) __builtin_va_copy(dst, src)
+
+/* Required in C11 for use with vprintf-family in <stdio.h>; harmless here. */
+typedef __builtin_va_list __gnuc_va_list;
+
+#endif
diff --git a/include/stdbool.h b/include/stdbool.h
@@ -0,0 +1,11 @@
+/* stdbool.h -- C11 7.18 -- Boolean type and values */
+#ifndef CFREE_STDBOOL_H
+#define CFREE_STDBOOL_H
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+#define __bool_true_false_are_defined 1
+
+#endif
diff --git a/include/stddef.h b/include/stddef.h
@@ -0,0 +1,23 @@
+/* stddef.h -- C11 7.19 -- Common definitions */
+#ifndef CFREE_STDDEF_H
+#define CFREE_STDDEF_H
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+
+/* C11 7.19: max_align_t is an object type whose alignment is the greatest
+ fundamental alignment. A struct holding the widest scalar types is the
+ conventional definition and matches what GCC/Clang use in their own
+ stddef.h. */
+typedef struct {
+ long long __cfree_ll;
+ long double __cfree_ld;
+} max_align_t;
+
+#undef NULL
+#define NULL ((void *)0)
+
+#define offsetof(type, member) __builtin_offsetof(type, member)
+
+#endif
diff --git a/include/stdint.h b/include/stdint.h
@@ -0,0 +1,147 @@
+/* stdint.h -- C11 7.20 -- Integer types of specified widths */
+#ifndef CFREE_STDINT_H
+#define CFREE_STDINT_H
+
+/* ------------------------------------------------------------------ */
+/* 7.20.1.1 Exact-width integer types */
+/* ------------------------------------------------------------------ */
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+
+typedef __UINT8_TYPE__ uint8_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+/* ------------------------------------------------------------------ */
+/* 7.20.1.2 Minimum-width integer types */
+/* ------------------------------------------------------------------ */
+typedef __INT_LEAST8_TYPE__ int_least8_t;
+typedef __INT_LEAST16_TYPE__ int_least16_t;
+typedef __INT_LEAST32_TYPE__ int_least32_t;
+typedef __INT_LEAST64_TYPE__ int_least64_t;
+
+typedef __UINT_LEAST8_TYPE__ uint_least8_t;
+typedef __UINT_LEAST16_TYPE__ uint_least16_t;
+typedef __UINT_LEAST32_TYPE__ uint_least32_t;
+typedef __UINT_LEAST64_TYPE__ uint_least64_t;
+
+/* ------------------------------------------------------------------ */
+/* 7.20.1.3 Fastest minimum-width integer types */
+/* ------------------------------------------------------------------ */
+typedef __INT_FAST8_TYPE__ int_fast8_t;
+typedef __INT_FAST16_TYPE__ int_fast16_t;
+typedef __INT_FAST32_TYPE__ int_fast32_t;
+typedef __INT_FAST64_TYPE__ int_fast64_t;
+
+typedef __UINT_FAST8_TYPE__ uint_fast8_t;
+typedef __UINT_FAST16_TYPE__ uint_fast16_t;
+typedef __UINT_FAST32_TYPE__ uint_fast32_t;
+typedef __UINT_FAST64_TYPE__ uint_fast64_t;
+
+/* ------------------------------------------------------------------ */
+/* 7.20.1.4 Integer types capable of holding object pointers */
+/* ------------------------------------------------------------------ */
+typedef __INTPTR_TYPE__ intptr_t;
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+/* ------------------------------------------------------------------ */
+/* 7.20.1.5 Greatest-width integer types */
+/* ------------------------------------------------------------------ */
+typedef __INTMAX_TYPE__ intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
+
+/* ------------------------------------------------------------------ */
+/* 7.20.2 Limits of specified-width integer types */
+/* ------------------------------------------------------------------ */
+
+/* exact-width */
+#define INT8_MAX __INT8_MAX__
+#define INT16_MAX __INT16_MAX__
+#define INT32_MAX __INT32_MAX__
+#define INT64_MAX __INT64_MAX__
+#define INT8_MIN (-INT8_MAX - 1)
+#define INT16_MIN (-INT16_MAX - 1)
+#define INT32_MIN (-INT32_MAX - 1)
+#define INT64_MIN (-INT64_MAX - 1)
+#define UINT8_MAX __UINT8_MAX__
+#define UINT16_MAX __UINT16_MAX__
+#define UINT32_MAX __UINT32_MAX__
+#define UINT64_MAX __UINT64_MAX__
+
+/* minimum-width */
+#define INT_LEAST8_MAX __INT_LEAST8_MAX__
+#define INT_LEAST16_MAX __INT_LEAST16_MAX__
+#define INT_LEAST32_MAX __INT_LEAST32_MAX__
+#define INT_LEAST64_MAX __INT_LEAST64_MAX__
+#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
+#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
+#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
+#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
+#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
+#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
+#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
+#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
+
+/* fastest minimum-width */
+#define INT_FAST8_MAX __INT_FAST8_MAX__
+#define INT_FAST16_MAX __INT_FAST16_MAX__
+#define INT_FAST32_MAX __INT_FAST32_MAX__
+#define INT_FAST64_MAX __INT_FAST64_MAX__
+#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
+#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
+#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
+#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
+#define UINT_FAST8_MAX __UINT_FAST8_MAX__
+#define UINT_FAST16_MAX __UINT_FAST16_MAX__
+#define UINT_FAST32_MAX __UINT_FAST32_MAX__
+#define UINT_FAST64_MAX __UINT_FAST64_MAX__
+
+/* pointer-holding */
+#define INTPTR_MAX __INTPTR_MAX__
+#define INTPTR_MIN (-INTPTR_MAX - 1)
+#define UINTPTR_MAX __UINTPTR_MAX__
+
+/* greatest-width */
+#define INTMAX_MAX __INTMAX_MAX__
+#define INTMAX_MIN (-INTMAX_MAX - 1)
+#define UINTMAX_MAX __UINTMAX_MAX__
+
+/* ------------------------------------------------------------------ */
+/* 7.20.3 Limits of other integer types defined in <stddef.h> etc. */
+/* ------------------------------------------------------------------ */
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
+
+#define SIZE_MAX __SIZE_MAX__
+
+#define WCHAR_MAX __WCHAR_MAX__
+#define WCHAR_MIN __WCHAR_MIN__
+
+#define WINT_MAX __WINT_MAX__
+#define WINT_MIN __WINT_MIN__
+
+/* sig_atomic_t bounds: defined in <signal.h>, which is not freestanding,
+ but the macros must still be exposed by <stdint.h>. */
+#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
+#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
+
+/* ------------------------------------------------------------------ */
+/* 7.20.4 Macros for integer constants */
+/* ------------------------------------------------------------------ */
+#define INT8_C(c) __INT8_C(c)
+#define INT16_C(c) __INT16_C(c)
+#define INT32_C(c) __INT32_C(c)
+#define INT64_C(c) __INT64_C(c)
+
+#define UINT8_C(c) __UINT8_C(c)
+#define UINT16_C(c) __UINT16_C(c)
+#define UINT32_C(c) __UINT32_C(c)
+#define UINT64_C(c) __UINT64_C(c)
+
+#define INTMAX_C(c) __INTMAX_C(c)
+#define UINTMAX_C(c) __UINTMAX_C(c)
+
+#endif
diff --git a/include/stdnoreturn.h b/include/stdnoreturn.h
@@ -0,0 +1,7 @@
+/* stdnoreturn.h -- C11 7.23 -- _Noreturn convenience macro */
+#ifndef CFREE_STDNORETURN_H
+#define CFREE_STDNORETURN_H
+
+#define noreturn _Noreturn
+
+#endif
diff --git a/test/smoke.c b/test/smoke.c
@@ -0,0 +1,104 @@
+/* Smoke test: every freestanding header should parse and expose its
+ required macros / typedefs. Compile with:
+ cc -std=c11 -ffreestanding -nostdinc -Iinclude -Wall -Wextra \
+ -Wpedantic -c test/smoke.c -o /tmp/smoke.o
+ No link step -- freestanding has no startup, no libc. */
+
+#include <float.h>
+#include <iso646.h>
+#include <limits.h>
+#include <stdalign.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdnoreturn.h>
+
+/* ---- compile-time assertions over the contracts ------------------ */
+
+_Static_assert(CHAR_BIT >= 8, "C11 5.2.4.2.1");
+_Static_assert(SCHAR_MIN <= -127, "C11 5.2.4.2.1");
+_Static_assert(SCHAR_MAX >= 127, "C11 5.2.4.2.1");
+_Static_assert(UCHAR_MAX >= 255, "C11 5.2.4.2.1");
+_Static_assert(SHRT_MIN <= -32767, "C11 5.2.4.2.1");
+_Static_assert(SHRT_MAX >= 32767, "C11 5.2.4.2.1");
+_Static_assert(INT_MIN <= -32767, "C11 5.2.4.2.1");
+_Static_assert(INT_MAX >= 32767, "C11 5.2.4.2.1");
+_Static_assert(LONG_MAX >= 2147483647L, "C11 5.2.4.2.1");
+_Static_assert(LLONG_MAX >= 9223372036854775807LL,"C11 5.2.4.2.1");
+_Static_assert(MB_LEN_MAX >= 1, "C11 5.2.4.2.1");
+
+_Static_assert(sizeof(int8_t) == 1, "exact width");
+_Static_assert(sizeof(int16_t) == 2, "exact width");
+_Static_assert(sizeof(int32_t) == 4, "exact width");
+_Static_assert(sizeof(int64_t) == 8, "exact width");
+_Static_assert(sizeof(uint8_t) == 1, "exact width");
+_Static_assert(sizeof(uint16_t) == 2, "exact width");
+_Static_assert(sizeof(uint32_t) == 4, "exact width");
+_Static_assert(sizeof(uint64_t) == 8, "exact width");
+
+_Static_assert(INT8_MAX == 127, "limits 7.20.2");
+_Static_assert(INT8_MIN == -128, "limits 7.20.2");
+_Static_assert(UINT8_MAX == 255, "limits 7.20.2");
+_Static_assert(INT64_MAX == 9223372036854775807LL,"limits 7.20.2");
+_Static_assert(UINT64_MAX == 18446744073709551615ULL,"limits 7.20.2");
+
+_Static_assert(sizeof(intptr_t) == sizeof(void *), "intptr_t holds void*");
+_Static_assert(sizeof(uintptr_t) == sizeof(void *), "uintptr_t holds void*");
+_Static_assert(sizeof(intmax_t) >= sizeof(long long), "intmax >= long long");
+
+_Static_assert(INT32_C(1) + INT32_C(2) == 3, "INT_C macros work");
+_Static_assert(UINT64_C(0xFFFFFFFFFFFFFFFF) == UINT64_MAX, "UINT64_C");
+
+/* iso646 substitutions */
+_Static_assert((1 and 1) == 1, "and");
+_Static_assert((1 or 0) == 1, "or");
+_Static_assert((compl 0) == -1, "compl");
+_Static_assert((1 xor 1) == 0, "xor");
+
+/* stdbool */
+_Static_assert(sizeof(bool) >= 1, "bool exists");
+_Static_assert(true == 1, "true");
+_Static_assert(false == 0, "false");
+_Static_assert(__bool_true_false_are_defined == 1, "marker macro");
+
+/* stdalign */
+_Static_assert(__alignof_is_defined == 1, "alignof marker");
+_Static_assert(__alignas_is_defined == 1, "alignas marker");
+_Static_assert(alignof(int) >= 1, "alignof works");
+alignas(16) static char aligned_buf[16];
+_Static_assert(alignof(max_align_t) >= alignof(long double), "max_align_t");
+
+/* stddef */
+_Static_assert(sizeof(size_t) == sizeof(sizeof(int)), "size_t");
+_Static_assert(sizeof(ptrdiff_t) == sizeof((int *)0 - (int *)0), "ptrdiff_t");
+
+struct s_off { char a; int b; };
+_Static_assert(offsetof(struct s_off, b) > 0, "offsetof");
+
+/* float.h: a few of the C11 minimums (5.2.4.2.2). */
+_Static_assert(FLT_RADIX >= 2, "5.2.4.2.2");
+_Static_assert(FLT_MANT_DIG >= 6, "5.2.4.2.2");
+_Static_assert(DBL_MANT_DIG >= FLT_MANT_DIG, "double >= float precision");
+_Static_assert(LDBL_MANT_DIG >= DBL_MANT_DIG, "long double >= double");
+_Static_assert(DECIMAL_DIG >= 10, "5.2.4.2.2");
+
+/* stdarg: must be usable in a vararg function. */
+static int sum_n(int n, ...) {
+ va_list ap;
+ va_start(ap, n);
+ int s = 0;
+ for (int i = 0; i < n; ++i) s += va_arg(ap, int);
+ va_end(ap);
+ return s;
+}
+
+/* stdnoreturn: macro must expand to a usable function specifier. */
+static noreturn void cfree_trap(void) { for (;;) {} }
+
+/* Reference everything so -Wunused-* stays quiet. */
+int cfree_smoke_ok(void) {
+ (void)aligned_buf;
+ if (0) cfree_trap();
+ return sum_n(3, 1, 2, 3) == 6;
+}