commit af964d3659842b90e2f7aa868fd3f6051f366a8a
parent ed7f379593b1990849bff38040e04435222cb9b0
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 18 Jun 2026 13:12:26 -0700
rt: expand freestanding libc surface
Diffstat:
13 files changed, 888 insertions(+), 0 deletions(-)
diff --git a/rt/include/inttypes.h b/rt/include/inttypes.h
@@ -0,0 +1,216 @@
+/* inttypes.h -- integer format macros and greatest-width conversions */
+#ifndef KIT_INTTYPES_H
+#define KIT_INTTYPES_H
+
+#include <stdint.h>
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
+
+intmax_t imaxabs(intmax_t j);
+imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);
+intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base);
+uintmax_t strtoumax(const char* restrict nptr, char** restrict endptr,
+ int base);
+
+#if __SIZEOF_LONG__ == 8
+#define __KIT_PRI64 "l"
+#define __KIT_SCN64 "l"
+#define __KIT_PRIMAX "l"
+#define __KIT_SCNMAX "l"
+#else
+#define __KIT_PRI64 "ll"
+#define __KIT_SCN64 "ll"
+#define __KIT_PRIMAX "ll"
+#define __KIT_SCNMAX "ll"
+#endif
+
+#if __SIZEOF_POINTER__ == __SIZEOF_LONG__
+#define __KIT_PRIPTR "l"
+#define __KIT_SCNPTR "l"
+#else
+#define __KIT_PRIPTR "ll"
+#define __KIT_SCNPTR "ll"
+#endif
+
+#if __SIZEOF_POINTER__ == 8
+#define __KIT_PRIFAST16 __KIT_PRI64
+#define __KIT_PRIFAST32 __KIT_PRI64
+#define __KIT_SCNFAST16 __KIT_SCN64
+#define __KIT_SCNFAST32 __KIT_SCN64
+#else
+#define __KIT_PRIFAST16 ""
+#define __KIT_PRIFAST32 ""
+#define __KIT_SCNFAST16 ""
+#define __KIT_SCNFAST32 ""
+#endif
+
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRId16 "d"
+#define PRIi16 "i"
+#define PRIo16 "o"
+#define PRIu16 "u"
+#define PRIx16 "x"
+#define PRIX16 "X"
+#define PRId32 "d"
+#define PRIi32 "i"
+#define PRIo32 "o"
+#define PRIu32 "u"
+#define PRIx32 "x"
+#define PRIX32 "X"
+#define PRId64 __KIT_PRI64 "d"
+#define PRIi64 __KIT_PRI64 "i"
+#define PRIo64 __KIT_PRI64 "o"
+#define PRIu64 __KIT_PRI64 "u"
+#define PRIx64 __KIT_PRI64 "x"
+#define PRIX64 __KIT_PRI64 "X"
+
+#define PRIdLEAST8 PRId8
+#define PRIiLEAST8 PRIi8
+#define PRIoLEAST8 PRIo8
+#define PRIuLEAST8 PRIu8
+#define PRIxLEAST8 PRIx8
+#define PRIXLEAST8 PRIX8
+#define PRIdLEAST16 PRId16
+#define PRIiLEAST16 PRIi16
+#define PRIoLEAST16 PRIo16
+#define PRIuLEAST16 PRIu16
+#define PRIxLEAST16 PRIx16
+#define PRIXLEAST16 PRIX16
+#define PRIdLEAST32 PRId32
+#define PRIiLEAST32 PRIi32
+#define PRIoLEAST32 PRIo32
+#define PRIuLEAST32 PRIu32
+#define PRIxLEAST32 PRIx32
+#define PRIXLEAST32 PRIX32
+#define PRIdLEAST64 PRId64
+#define PRIiLEAST64 PRIi64
+#define PRIoLEAST64 PRIo64
+#define PRIuLEAST64 PRIu64
+#define PRIxLEAST64 PRIx64
+#define PRIXLEAST64 PRIX64
+
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+#define PRIdFAST16 __KIT_PRIFAST16 "d"
+#define PRIiFAST16 __KIT_PRIFAST16 "i"
+#define PRIoFAST16 __KIT_PRIFAST16 "o"
+#define PRIuFAST16 __KIT_PRIFAST16 "u"
+#define PRIxFAST16 __KIT_PRIFAST16 "x"
+#define PRIXFAST16 __KIT_PRIFAST16 "X"
+#define PRIdFAST32 __KIT_PRIFAST32 "d"
+#define PRIiFAST32 __KIT_PRIFAST32 "i"
+#define PRIoFAST32 __KIT_PRIFAST32 "o"
+#define PRIuFAST32 __KIT_PRIFAST32 "u"
+#define PRIxFAST32 __KIT_PRIFAST32 "x"
+#define PRIXFAST32 __KIT_PRIFAST32 "X"
+#define PRIdFAST64 PRId64
+#define PRIiFAST64 PRIi64
+#define PRIoFAST64 PRIo64
+#define PRIuFAST64 PRIu64
+#define PRIxFAST64 PRIx64
+#define PRIXFAST64 PRIX64
+
+#define PRIdMAX __KIT_PRIMAX "d"
+#define PRIiMAX __KIT_PRIMAX "i"
+#define PRIoMAX __KIT_PRIMAX "o"
+#define PRIuMAX __KIT_PRIMAX "u"
+#define PRIxMAX __KIT_PRIMAX "x"
+#define PRIXMAX __KIT_PRIMAX "X"
+
+#define PRIdPTR __KIT_PRIPTR "d"
+#define PRIiPTR __KIT_PRIPTR "i"
+#define PRIoPTR __KIT_PRIPTR "o"
+#define PRIuPTR __KIT_PRIPTR "u"
+#define PRIxPTR __KIT_PRIPTR "x"
+#define PRIXPTR __KIT_PRIPTR "X"
+
+#define SCNd8 "hhd"
+#define SCNi8 "hhi"
+#define SCNo8 "hho"
+#define SCNu8 "hhu"
+#define SCNx8 "hhx"
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNd32 "d"
+#define SCNi32 "i"
+#define SCNo32 "o"
+#define SCNu32 "u"
+#define SCNx32 "x"
+#define SCNd64 __KIT_SCN64 "d"
+#define SCNi64 __KIT_SCN64 "i"
+#define SCNo64 __KIT_SCN64 "o"
+#define SCNu64 __KIT_SCN64 "u"
+#define SCNx64 __KIT_SCN64 "x"
+
+#define SCNdLEAST8 SCNd8
+#define SCNiLEAST8 SCNi8
+#define SCNoLEAST8 SCNo8
+#define SCNuLEAST8 SCNu8
+#define SCNxLEAST8 SCNx8
+#define SCNdLEAST16 SCNd16
+#define SCNiLEAST16 SCNi16
+#define SCNoLEAST16 SCNo16
+#define SCNuLEAST16 SCNu16
+#define SCNxLEAST16 SCNx16
+#define SCNdLEAST32 SCNd32
+#define SCNiLEAST32 SCNi32
+#define SCNoLEAST32 SCNo32
+#define SCNuLEAST32 SCNu32
+#define SCNxLEAST32 SCNx32
+#define SCNdLEAST64 SCNd64
+#define SCNiLEAST64 SCNi64
+#define SCNoLEAST64 SCNo64
+#define SCNuLEAST64 SCNu64
+#define SCNxLEAST64 SCNx64
+
+#define SCNdFAST8 SCNd8
+#define SCNiFAST8 SCNi8
+#define SCNoFAST8 SCNo8
+#define SCNuFAST8 SCNu8
+#define SCNxFAST8 SCNx8
+#define SCNdFAST16 __KIT_SCNFAST16 "d"
+#define SCNiFAST16 __KIT_SCNFAST16 "i"
+#define SCNoFAST16 __KIT_SCNFAST16 "o"
+#define SCNuFAST16 __KIT_SCNFAST16 "u"
+#define SCNxFAST16 __KIT_SCNFAST16 "x"
+#define SCNdFAST32 __KIT_SCNFAST32 "d"
+#define SCNiFAST32 __KIT_SCNFAST32 "i"
+#define SCNoFAST32 __KIT_SCNFAST32 "o"
+#define SCNuFAST32 __KIT_SCNFAST32 "u"
+#define SCNxFAST32 __KIT_SCNFAST32 "x"
+#define SCNdFAST64 SCNd64
+#define SCNiFAST64 SCNi64
+#define SCNoFAST64 SCNo64
+#define SCNuFAST64 SCNu64
+#define SCNxFAST64 SCNx64
+
+#define SCNdMAX __KIT_SCNMAX "d"
+#define SCNiMAX __KIT_SCNMAX "i"
+#define SCNoMAX __KIT_SCNMAX "o"
+#define SCNuMAX __KIT_SCNMAX "u"
+#define SCNxMAX __KIT_SCNMAX "x"
+
+#define SCNdPTR __KIT_SCNPTR "d"
+#define SCNiPTR __KIT_SCNPTR "i"
+#define SCNoPTR __KIT_SCNPTR "o"
+#define SCNuPTR __KIT_SCNPTR "u"
+#define SCNxPTR __KIT_SCNPTR "x"
+
+#define __STDC_VERSION_INTTYPES_H__ 202311L
+
+#endif
diff --git a/rt/include/limits.h b/rt/include/limits.h
@@ -14,6 +14,18 @@
#define KIT_LIMITS_H
#define CHAR_BIT 8
+#define BOOL_WIDTH 1
+#define CHAR_WIDTH 8
+#define SCHAR_WIDTH 8
+#define UCHAR_WIDTH 8
+#define SHRT_WIDTH 16
+#define USHRT_WIDTH 16
+#define INT_WIDTH 32
+#define UINT_WIDTH 32
+#define LONG_WIDTH (__SIZEOF_LONG__ * CHAR_BIT)
+#define ULONG_WIDTH (__SIZEOF_LONG__ * CHAR_BIT)
+#define LLONG_WIDTH 64
+#define ULLONG_WIDTH 64
#define MB_LEN_MAX 1 /* freestanding has no locale; smallest legal value */
/* signed / unsigned char */
diff --git a/rt/include/stdbit.h b/rt/include/stdbit.h
@@ -0,0 +1,417 @@
+/* stdbit.h -- C23 7.18a -- Bit and byte utilities */
+#ifndef KIT_STDBIT_H
+#define KIT_STDBIT_H
+
+#include <stdbool.h>
+#include <limits.h>
+
+#define __STDC_VERSION_STDBIT_H__ 202311L
+
+#define __STDC_ENDIAN_LITTLE__ 1234
+#define __STDC_ENDIAN_BIG__ 4321
+#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__
+#else
+#define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
+#endif
+
+#define __KIT_STDBIT_WIDTH(T) ((unsigned)(sizeof(T) * CHAR_BIT))
+
+static inline unsigned int stdc_leading_zeros_uc(unsigned char v) {
+ unsigned int w = __KIT_STDBIT_WIDTH(unsigned char);
+ if (v == 0) return w;
+ return (unsigned int)__builtin_clz((unsigned int)v) -
+ (__KIT_STDBIT_WIDTH(unsigned int) - w);
+}
+
+static inline unsigned int stdc_leading_zeros_us(unsigned short v) {
+ unsigned int w = __KIT_STDBIT_WIDTH(unsigned short);
+ if (v == 0) return w;
+ return (unsigned int)__builtin_clz((unsigned int)v) -
+ (__KIT_STDBIT_WIDTH(unsigned int) - w);
+}
+
+static inline unsigned int stdc_leading_zeros_ui(unsigned int v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned int);
+ return (unsigned int)__builtin_clz(v);
+}
+
+static inline unsigned int stdc_leading_zeros_ul(unsigned long v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned long);
+#if __SIZEOF_LONG__ == 8
+ return (unsigned int)__builtin_clzll((unsigned long long)v);
+#else
+ return (unsigned int)__builtin_clz((unsigned int)v);
+#endif
+}
+
+static inline unsigned int stdc_leading_zeros_ull(unsigned long long v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned long long);
+ return (unsigned int)__builtin_clzll(v);
+}
+
+static inline unsigned int stdc_trailing_zeros_uc(unsigned char v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned char);
+ return (unsigned int)__builtin_ctz((unsigned int)v);
+}
+
+static inline unsigned int stdc_trailing_zeros_us(unsigned short v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned short);
+ return (unsigned int)__builtin_ctz((unsigned int)v);
+}
+
+static inline unsigned int stdc_trailing_zeros_ui(unsigned int v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned int);
+ return (unsigned int)__builtin_ctz(v);
+}
+
+static inline unsigned int stdc_trailing_zeros_ul(unsigned long v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned long);
+#if __SIZEOF_LONG__ == 8
+ return (unsigned int)__builtin_ctzll((unsigned long long)v);
+#else
+ return (unsigned int)__builtin_ctz((unsigned int)v);
+#endif
+}
+
+static inline unsigned int stdc_trailing_zeros_ull(unsigned long long v) {
+ if (v == 0) return __KIT_STDBIT_WIDTH(unsigned long long);
+ return (unsigned int)__builtin_ctzll(v);
+}
+
+static inline unsigned int stdc_count_ones_uc(unsigned char v) {
+ unsigned int n = 0;
+ while (v != 0) {
+ n += (unsigned int)(v & 1u);
+ v = (unsigned char)(v >> 1u);
+ }
+ return n;
+}
+
+static inline unsigned int stdc_count_ones_us(unsigned short v) {
+ unsigned int n = 0;
+ while (v != 0) {
+ n += (unsigned int)(v & 1u);
+ v = (unsigned short)(v >> 1u);
+ }
+ return n;
+}
+
+static inline unsigned int stdc_count_ones_ui(unsigned int v) {
+ unsigned int n = 0;
+ while (v != 0) {
+ n += v & 1u;
+ v >>= 1u;
+ }
+ return n;
+}
+
+static inline unsigned int stdc_count_ones_ul(unsigned long v) {
+ unsigned int n = 0;
+ while (v != 0) {
+ n += (unsigned int)(v & 1ul);
+ v >>= 1u;
+ }
+ return n;
+}
+
+static inline unsigned int stdc_count_ones_ull(unsigned long long v) {
+ unsigned int n = 0;
+ while (v != 0) {
+ n += (unsigned int)(v & 1ull);
+ v >>= 1u;
+ }
+ return n;
+}
+
+static inline unsigned int stdc_leading_ones_uc(unsigned char v) {
+ return stdc_leading_zeros_uc((unsigned char)~v);
+}
+static inline unsigned int stdc_leading_ones_us(unsigned short v) {
+ return stdc_leading_zeros_us((unsigned short)~v);
+}
+static inline unsigned int stdc_leading_ones_ui(unsigned int v) {
+ return stdc_leading_zeros_ui(~v);
+}
+static inline unsigned int stdc_leading_ones_ul(unsigned long v) {
+ return stdc_leading_zeros_ul(~v);
+}
+static inline unsigned int stdc_leading_ones_ull(unsigned long long v) {
+ return stdc_leading_zeros_ull(~v);
+}
+
+static inline unsigned int stdc_trailing_ones_uc(unsigned char v) {
+ return stdc_trailing_zeros_uc((unsigned char)~v);
+}
+static inline unsigned int stdc_trailing_ones_us(unsigned short v) {
+ return stdc_trailing_zeros_us((unsigned short)~v);
+}
+static inline unsigned int stdc_trailing_ones_ui(unsigned int v) {
+ return stdc_trailing_zeros_ui(~v);
+}
+static inline unsigned int stdc_trailing_ones_ul(unsigned long v) {
+ return stdc_trailing_zeros_ul(~v);
+}
+static inline unsigned int stdc_trailing_ones_ull(unsigned long long v) {
+ return stdc_trailing_zeros_ull(~v);
+}
+
+static inline unsigned int stdc_count_zeros_uc(unsigned char v) {
+ return __KIT_STDBIT_WIDTH(unsigned char) - stdc_count_ones_uc(v);
+}
+static inline unsigned int stdc_count_zeros_us(unsigned short v) {
+ return __KIT_STDBIT_WIDTH(unsigned short) - stdc_count_ones_us(v);
+}
+static inline unsigned int stdc_count_zeros_ui(unsigned int v) {
+ return __KIT_STDBIT_WIDTH(unsigned int) - stdc_count_ones_ui(v);
+}
+static inline unsigned int stdc_count_zeros_ul(unsigned long v) {
+ return __KIT_STDBIT_WIDTH(unsigned long) - stdc_count_ones_ul(v);
+}
+static inline unsigned int stdc_count_zeros_ull(unsigned long long v) {
+ return __KIT_STDBIT_WIDTH(unsigned long long) - stdc_count_ones_ull(v);
+}
+
+static inline bool stdc_has_single_bit_uc(unsigned char v) {
+ return v != 0 && (unsigned char)(v & (unsigned char)(v - 1u)) == 0;
+}
+static inline bool stdc_has_single_bit_us(unsigned short v) {
+ return v != 0 && (unsigned short)(v & (unsigned short)(v - 1u)) == 0;
+}
+static inline bool stdc_has_single_bit_ui(unsigned int v) {
+ return v != 0 && (v & (v - 1u)) == 0;
+}
+static inline bool stdc_has_single_bit_ul(unsigned long v) {
+ return v != 0 && (v & (v - 1ul)) == 0;
+}
+static inline bool stdc_has_single_bit_ull(unsigned long long v) {
+ return v != 0 && (v & (v - 1ull)) == 0;
+}
+
+static inline unsigned int stdc_bit_width_uc(unsigned char v) {
+ return __KIT_STDBIT_WIDTH(unsigned char) - stdc_leading_zeros_uc(v);
+}
+static inline unsigned int stdc_bit_width_us(unsigned short v) {
+ return __KIT_STDBIT_WIDTH(unsigned short) - stdc_leading_zeros_us(v);
+}
+static inline unsigned int stdc_bit_width_ui(unsigned int v) {
+ return __KIT_STDBIT_WIDTH(unsigned int) - stdc_leading_zeros_ui(v);
+}
+static inline unsigned int stdc_bit_width_ul(unsigned long v) {
+ return __KIT_STDBIT_WIDTH(unsigned long) - stdc_leading_zeros_ul(v);
+}
+static inline unsigned int stdc_bit_width_ull(unsigned long long v) {
+ return __KIT_STDBIT_WIDTH(unsigned long long) - stdc_leading_zeros_ull(v);
+}
+
+static inline unsigned char stdc_bit_floor_uc(unsigned char v) {
+ return v == 0 ? 0 : (unsigned char)(1u << (stdc_bit_width_uc(v) - 1u));
+}
+static inline unsigned short stdc_bit_floor_us(unsigned short v) {
+ return v == 0 ? 0 : (unsigned short)(1u << (stdc_bit_width_us(v) - 1u));
+}
+static inline unsigned int stdc_bit_floor_ui(unsigned int v) {
+ return v == 0 ? 0 : (1u << (stdc_bit_width_ui(v) - 1u));
+}
+static inline unsigned long stdc_bit_floor_ul(unsigned long v) {
+ return v == 0 ? 0 : (1ul << (stdc_bit_width_ul(v) - 1u));
+}
+static inline unsigned long long stdc_bit_floor_ull(unsigned long long v) {
+ return v == 0 ? 0 : (1ull << (stdc_bit_width_ull(v) - 1u));
+}
+
+static inline unsigned char stdc_bit_ceil_uc(unsigned char v) {
+ unsigned int w;
+ if (v <= 1u) return 1u;
+ w = stdc_bit_width_uc((unsigned char)(v - 1u));
+ return w >= __KIT_STDBIT_WIDTH(unsigned char) ? 0 : (unsigned char)(1u << w);
+}
+static inline unsigned short stdc_bit_ceil_us(unsigned short v) {
+ unsigned int w;
+ if (v <= 1u) return 1u;
+ w = stdc_bit_width_us((unsigned short)(v - 1u));
+ return w >= __KIT_STDBIT_WIDTH(unsigned short) ? 0
+ : (unsigned short)(1u << w);
+}
+static inline unsigned int stdc_bit_ceil_ui(unsigned int v) {
+ unsigned int w;
+ if (v <= 1u) return 1u;
+ w = stdc_bit_width_ui(v - 1u);
+ return w >= __KIT_STDBIT_WIDTH(unsigned int) ? 0 : (1u << w);
+}
+static inline unsigned long stdc_bit_ceil_ul(unsigned long v) {
+ unsigned int w;
+ if (v <= 1ul) return 1ul;
+ w = stdc_bit_width_ul(v - 1ul);
+ return w >= __KIT_STDBIT_WIDTH(unsigned long) ? 0 : (1ul << w);
+}
+static inline unsigned long long stdc_bit_ceil_ull(unsigned long long v) {
+ unsigned int w;
+ if (v <= 1ull) return 1ull;
+ w = stdc_bit_width_ull(v - 1ull);
+ return w >= __KIT_STDBIT_WIDTH(unsigned long long) ? 0 : (1ull << w);
+}
+
+static inline unsigned int stdc_first_leading_zero_uc(unsigned char v) {
+ return v == (unsigned char)~0u ? 0 : stdc_leading_ones_uc(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_zero_us(unsigned short v) {
+ return v == (unsigned short)~0u ? 0 : stdc_leading_ones_us(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_zero_ui(unsigned int v) {
+ return v == ~0u ? 0 : stdc_leading_ones_ui(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_zero_ul(unsigned long v) {
+ return v == ~0ul ? 0 : stdc_leading_ones_ul(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_zero_ull(unsigned long long v) {
+ return v == ~0ull ? 0 : stdc_leading_ones_ull(v) + 1u;
+}
+
+static inline unsigned int stdc_first_leading_one_uc(unsigned char v) {
+ return v == 0 ? 0 : stdc_leading_zeros_uc(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_one_us(unsigned short v) {
+ return v == 0 ? 0 : stdc_leading_zeros_us(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_one_ui(unsigned int v) {
+ return v == 0 ? 0 : stdc_leading_zeros_ui(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_one_ul(unsigned long v) {
+ return v == 0 ? 0 : stdc_leading_zeros_ul(v) + 1u;
+}
+static inline unsigned int stdc_first_leading_one_ull(unsigned long long v) {
+ return v == 0 ? 0 : stdc_leading_zeros_ull(v) + 1u;
+}
+
+static inline unsigned int stdc_first_trailing_zero_uc(unsigned char v) {
+ return v == (unsigned char)~0u ? 0 : stdc_trailing_ones_uc(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_zero_us(unsigned short v) {
+ return v == (unsigned short)~0u ? 0 : stdc_trailing_ones_us(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_zero_ui(unsigned int v) {
+ return v == ~0u ? 0 : stdc_trailing_ones_ui(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_zero_ul(unsigned long v) {
+ return v == ~0ul ? 0 : stdc_trailing_ones_ul(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_zero_ull(unsigned long long v) {
+ return v == ~0ull ? 0 : stdc_trailing_ones_ull(v) + 1u;
+}
+
+static inline unsigned int stdc_first_trailing_one_uc(unsigned char v) {
+ return v == 0 ? 0 : stdc_trailing_zeros_uc(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_one_us(unsigned short v) {
+ return v == 0 ? 0 : stdc_trailing_zeros_us(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_one_ui(unsigned int v) {
+ return v == 0 ? 0 : stdc_trailing_zeros_ui(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_one_ul(unsigned long v) {
+ return v == 0 ? 0 : stdc_trailing_zeros_ul(v) + 1u;
+}
+static inline unsigned int stdc_first_trailing_one_ull(unsigned long long v) {
+ return v == 0 ? 0 : stdc_trailing_zeros_ull(v) + 1u;
+}
+
+#define __KIT_STDBIT_WIDTH_EXPR(v) ((unsigned)(sizeof(v) * CHAR_BIT))
+
+static inline unsigned long long __kit_stdbit_mask(unsigned int width) {
+ return width >= __KIT_STDBIT_WIDTH(unsigned long long)
+ ? ~0ull
+ : ((1ull << width) - 1ull);
+}
+
+static inline unsigned int __kit_stdbit_lz(unsigned long long v,
+ unsigned int width) {
+ v &= __kit_stdbit_mask(width);
+ if (v == 0) return width;
+ return (unsigned int)__builtin_clzll(v) -
+ (__KIT_STDBIT_WIDTH(unsigned long long) - width);
+}
+
+static inline unsigned int __kit_stdbit_tz(unsigned long long v,
+ unsigned int width) {
+ v &= __kit_stdbit_mask(width);
+ if (v == 0) return width;
+ return (unsigned int)__builtin_ctzll(v);
+}
+
+static inline unsigned int __kit_stdbit_pop(unsigned long long v,
+ unsigned int width) {
+ unsigned int n = 0;
+ v &= __kit_stdbit_mask(width);
+ while (v != 0) {
+ n += (unsigned int)(v & 1ull);
+ v >>= 1u;
+ }
+ return n;
+}
+
+static inline unsigned long long __kit_stdbit_floor(unsigned long long v,
+ unsigned int width) {
+ unsigned int w;
+ v &= __kit_stdbit_mask(width);
+ if (v == 0) return 0;
+ w = width - __kit_stdbit_lz(v, width) - 1u;
+ return 1ull << w;
+}
+
+static inline unsigned long long __kit_stdbit_ceil(unsigned long long v,
+ unsigned int width) {
+ unsigned int w;
+ v &= __kit_stdbit_mask(width);
+ if (v <= 1ull) return 1ull;
+ w = width - __kit_stdbit_lz(v - 1ull, width);
+ return w >= width ? 0ull : (1ull << w);
+}
+
+static inline bool __kit_stdbit_single(unsigned long long v,
+ unsigned int width) {
+ v &= __kit_stdbit_mask(width);
+ return v != 0 && (v & (v - 1ull)) == 0;
+}
+
+static inline unsigned int __kit_stdbit_first_lz(unsigned long long v,
+ unsigned int width) {
+ unsigned int n = __kit_stdbit_lz(v, width);
+ return n == width ? 0u : n + 1u;
+}
+
+static inline unsigned int __kit_stdbit_first_tz(unsigned long long v,
+ unsigned int width) {
+ unsigned int n = __kit_stdbit_tz(v, width);
+ return n == width ? 0u : n + 1u;
+}
+
+#define stdc_leading_zeros(v) \
+ __kit_stdbit_lz((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_leading_ones(v) \
+ __kit_stdbit_lz(~(unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_trailing_zeros(v) \
+ __kit_stdbit_tz((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_trailing_ones(v) \
+ __kit_stdbit_tz(~(unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_first_leading_zero(v) \
+ __kit_stdbit_first_lz(~(unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_first_leading_one(v) \
+ __kit_stdbit_first_lz((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_first_trailing_zero(v) \
+ __kit_stdbit_first_tz(~(unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_first_trailing_one(v) \
+ __kit_stdbit_first_tz((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_count_ones(v) \
+ __kit_stdbit_pop((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_count_zeros(v) (__KIT_STDBIT_WIDTH_EXPR(v) - stdc_count_ones(v))
+#define stdc_has_single_bit(v) \
+ __kit_stdbit_single((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_bit_width(v) \
+ (__KIT_STDBIT_WIDTH_EXPR(v) - stdc_leading_zeros(v))
+#define stdc_bit_floor(v) \
+ __kit_stdbit_floor((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+#define stdc_bit_ceil(v) \
+ __kit_stdbit_ceil((unsigned long long)(v), __KIT_STDBIT_WIDTH_EXPR(v))
+
+#endif
diff --git a/rt/include/stdckdint.h b/rt/include/stdckdint.h
@@ -0,0 +1,13 @@
+/* stdckdint.h -- C23 7.20 -- Checked integer arithmetic */
+#ifndef KIT_STDCKDINT_H
+#define KIT_STDCKDINT_H
+
+#include <stdbool.h>
+
+#define __STDC_VERSION_STDCKDINT_H__ 202311L
+
+#define ckd_add(result, a, b) __builtin_add_overflow((a), (b), (result))
+#define ckd_sub(result, a, b) __builtin_sub_overflow((a), (b), (result))
+#define ckd_mul(result, a, b) __builtin_mul_overflow((a), (b), (result))
+
+#endif
diff --git a/rt/include/stddef.h b/rt/include/stddef.h
@@ -19,5 +19,8 @@ typedef struct {
#define NULL ((void*)0)
#define offsetof(type, member) __builtin_offsetof(type, member)
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define unreachable() __builtin_unreachable()
+#endif
#endif
diff --git a/rt/include/stdint.h b/rt/include/stdint.h
@@ -140,6 +140,49 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
+#define INT8_WIDTH 8
+#define INT16_WIDTH 16
+#define INT32_WIDTH 32
+#define INT64_WIDTH 64
+#define UINT8_WIDTH 8
+#define UINT16_WIDTH 16
+#define UINT32_WIDTH 32
+#define UINT64_WIDTH 64
+#define INT_LEAST8_WIDTH 8
+#define INT_LEAST16_WIDTH 16
+#define INT_LEAST32_WIDTH 32
+#define INT_LEAST64_WIDTH 64
+#define UINT_LEAST8_WIDTH 8
+#define UINT_LEAST16_WIDTH 16
+#define UINT_LEAST32_WIDTH 32
+#define UINT_LEAST64_WIDTH 64
+#define INT_FAST8_WIDTH 8
+#define UINT_FAST8_WIDTH 8
+#if __SIZEOF_POINTER__ == 8
+#define INT_FAST16_WIDTH 64
+#define INT_FAST32_WIDTH 64
+#define INT_FAST64_WIDTH 64
+#define UINT_FAST16_WIDTH 64
+#define UINT_FAST32_WIDTH 64
+#define UINT_FAST64_WIDTH 64
+#else
+#define INT_FAST16_WIDTH 32
+#define INT_FAST32_WIDTH 32
+#define INT_FAST64_WIDTH 64
+#define UINT_FAST16_WIDTH 32
+#define UINT_FAST32_WIDTH 32
+#define UINT_FAST64_WIDTH 64
+#endif
+#define INTPTR_WIDTH (__SIZEOF_POINTER__ * 8)
+#define UINTPTR_WIDTH (__SIZEOF_POINTER__ * 8)
+#define INTMAX_WIDTH 64
+#define UINTMAX_WIDTH 64
+#define PTRDIFF_WIDTH (__SIZEOF_PTRDIFF_T__ * 8)
+#define SIZE_WIDTH (__SIZEOF_SIZE_T__ * 8)
+#define WCHAR_WIDTH (__SIZEOF_WCHAR_T__ * 8)
+#define WINT_WIDTH (__SIZEOF_WINT_T__ * 8)
+#define SIG_ATOMIC_WIDTH 32
+
/* ------------------------------------------------------------------ */
/* 7.20.4 Macros for integer constants */
/* ------------------------------------------------------------------ */
diff --git a/rt/include/stdlib.h b/rt/include/stdlib.h
@@ -31,6 +31,7 @@ long strtol(const char* nptr, char** endptr, int base);
long long strtoll(const char* nptr, char** endptr, int base);
unsigned long strtoul(const char* nptr, char** endptr, int base);
unsigned long long strtoull(const char* nptr, char** endptr, int base);
+size_t memalignment(const void* p);
int abs(int j);
long labs(long j);
diff --git a/rt/include/string.h b/rt/include/string.h
@@ -7,8 +7,10 @@
void* memcpy(void* dest, const void* src, size_t n);
void* memmove(void* dest, const void* src, size_t n);
void* memset(void* s, int c, size_t n);
+void* memset_explicit(void* s, int c, size_t n);
int memcmp(const void* s1, const void* s2, size_t n);
void* memchr(const void* s, int c, size_t n);
+void* memccpy(void* dest, const void* src, int c, size_t n);
char* strcpy(char* dest, const char* src);
char* strncpy(char* dest, const char* src, size_t n);
@@ -18,8 +20,13 @@ int strcmp(const char* s1, const char* s2);
int strncmp(const char* s1, const char* s2, size_t n);
char* strchr(const char* s, int c);
char* strrchr(const char* s, int c);
+size_t strspn(const char* s, const char* accept);
+size_t strcspn(const char* s, const char* reject);
+char* strpbrk(const char* s, const char* accept);
char* strstr(const char* haystack, const char* needle);
size_t strlen(const char* s);
size_t strnlen(const char* s, size_t maxlen);
+#define __STDC_VERSION_STRING_H__ 202311L
+
#endif
diff --git a/rt/lib/mem/mem.c b/rt/lib/mem/mem.c
@@ -36,6 +36,13 @@ __attribute__((weak)) void* memset(void* dst, int c, size_t n) {
return dst;
}
+__attribute__((weak)) void* memset_explicit(void* dst, int c, size_t n) {
+ volatile unsigned char* d = (volatile unsigned char*)dst;
+ unsigned char v = (unsigned char)c;
+ for (size_t i = 0; i < n; i++) d[i] = v;
+ return dst;
+}
+
__attribute__((weak)) int memcmp(const void* a, const void* b, size_t n) {
const unsigned char* p = (const unsigned char*)a;
const unsigned char* q = (const unsigned char*)b;
diff --git a/rt/lib/stdlib/stdlib.c b/rt/lib/stdlib/stdlib.c
@@ -178,6 +178,42 @@ __attribute__((weak)) float strtof(const char* nptr, char** endptr) {
return (float)kit_strtold_impl(nptr, endptr);
}
+__attribute__((weak)) size_t memalignment(const void* p) {
+ __UINTPTR_TYPE__ v = (__UINTPTR_TYPE__)p;
+ if (v == 0) return 0;
+ return (size_t)(v & (0u - v));
+}
+
+typedef __INTMAX_TYPE__ kit_intmax_t;
+typedef __UINTMAX_TYPE__ kit_uintmax_t;
+
+typedef struct {
+ kit_intmax_t quot;
+ kit_intmax_t rem;
+} imaxdiv_t;
+
+__attribute__((weak)) kit_intmax_t imaxabs(kit_intmax_t j) {
+ return j < 0 ? -j : j;
+}
+
+__attribute__((weak)) imaxdiv_t imaxdiv(kit_intmax_t numer,
+ kit_intmax_t denom) {
+ imaxdiv_t r;
+ r.quot = numer / denom;
+ r.rem = numer % denom;
+ return r;
+}
+
+__attribute__((weak)) kit_intmax_t strtoimax(const char* nptr, char** endptr,
+ int base) {
+ return (kit_intmax_t)strtoll(nptr, endptr, base);
+}
+
+__attribute__((weak)) kit_uintmax_t strtoumax(const char* nptr, char** endptr,
+ int base) {
+ return (kit_uintmax_t)strtoull(nptr, endptr, base);
+}
+
__attribute__((weak)) int abs(int j) { return j < 0 ? -j : j; }
__attribute__((weak)) long labs(long j) { return j < 0 ? -j : j; }
__attribute__((weak)) long long llabs(long long j) { return j < 0 ? -j : j; }
diff --git a/rt/lib/string/string.c b/rt/lib/string/string.c
@@ -14,6 +14,18 @@ __attribute__((weak)) void* memchr(const void* s, int c, size_t n) {
return NULL;
}
+__attribute__((weak)) void* memccpy(void* dest, const void* src, int c,
+ size_t n) {
+ unsigned char* d = (unsigned char*)dest;
+ const unsigned char* s = (const unsigned char*)src;
+ unsigned char v = (unsigned char)c;
+ for (size_t i = 0; i < n; i++) {
+ d[i] = s[i];
+ if (s[i] == v) return d + i + 1u;
+ }
+ return NULL;
+}
+
__attribute__((weak)) size_t strlen(const char* s) {
size_t n = 0;
while (s[n] != '\0') n++;
@@ -94,6 +106,34 @@ __attribute__((weak)) char* strrchr(const char* s, int c) {
}
}
+static int kit_str_contains(const char* s, char c) {
+ while (*s != '\0') {
+ if (*s == c) return 1;
+ s++;
+ }
+ return 0;
+}
+
+__attribute__((weak)) size_t strspn(const char* s, const char* accept) {
+ size_t n = 0;
+ while (s[n] != '\0' && kit_str_contains(accept, s[n])) n++;
+ return n;
+}
+
+__attribute__((weak)) size_t strcspn(const char* s, const char* reject) {
+ size_t n = 0;
+ while (s[n] != '\0' && !kit_str_contains(reject, s[n])) n++;
+ return n;
+}
+
+__attribute__((weak)) char* strpbrk(const char* s, const char* accept) {
+ while (*s != '\0') {
+ if (kit_str_contains(accept, *s)) return (char*)s;
+ s++;
+ }
+ return NULL;
+}
+
__attribute__((weak)) char* strstr(const char* haystack, const char* needle) {
if (*needle == '\0') return (char*)haystack;
for (; *haystack != '\0'; haystack++) {
diff --git a/test/rt/cases/freestanding_lib.c b/test/rt/cases/freestanding_lib.c
@@ -1,6 +1,11 @@
#include <assert.h>
+#include <inttypes.h>
+#include <limits.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdbit.h>
+#include <stdckdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -63,10 +68,19 @@ static int strings_ok(void) {
if (strnlen(buf, 4) != 4) return 0;
if (strchr(buf, ' ') != buf + 5) return 0;
if (strrchr(buf, 'a') != buf + 9) return 0;
+ if (strspn(buf, "alph ") != 6) return 0;
+ if (strcspn(buf, "tb") != 6) return 0;
+ if (strpbrk(buf, "tb") != buf + 6) return 0;
if (strstr(buf, "ha be") != buf + 3) return 0;
strncpy(small, "xy", sizeof(small));
if (small[0] != 'x' || small[1] != 'y' || small[2] != '\0') return 0;
+
+ memset(small, '?', sizeof(small));
+ if (memccpy(small, "abcd", 'c', 4) != small + 3) return 0;
+ if (memcmp(small, "abc?", 4) != 0) return 0;
+ memset_explicit(small, 0, sizeof(small));
+ if (small[0] != '\0' || small[sizeof(small) - 1] != '\0') return 0;
return 1;
}
@@ -78,6 +92,8 @@ static int stdlib_ok(void) {
div_t d;
ldiv_t ld;
lldiv_t lld;
+ imaxdiv_t imd;
+ char aligned[32];
if (atoi(" -42x") != -42) return 0;
if (atol("123") != 123L) return 0;
@@ -89,14 +105,27 @@ static int stdlib_ok(void) {
if ((int)(strtod("12.5e1z", &end) + 0.5) != 125 || *end != 'z') return 0;
if ((int)(strtof("4.25", &end) * 4.0f) != 17 || *end != '\0') return 0;
if ((int)strtold("9.0", &end) != 9 || *end != '\0') return 0;
+ if (strtoimax("-9223372036854775807", &end, 10) !=
+ (intmax_t)-9223372036854775807LL ||
+ *end != '\0')
+ return 0;
+ if (strtoumax("18446744073709551615", &end, 10) !=
+ (uintmax_t)18446744073709551615ULL ||
+ *end != '\0')
+ return 0;
if (abs(-7) != 7 || labs(-8L) != 8L || llabs(-9LL) != 9LL) return 0;
+ if (imaxabs((intmax_t)-10) != (intmax_t)10) return 0;
d = div(17, 5);
ld = ldiv(17L, 5L);
lld = lldiv(17LL, 5LL);
+ imd = imaxdiv((intmax_t)17, (intmax_t)5);
if (d.quot != 3 || d.rem != 2) return 0;
if (ld.quot != 3 || ld.rem != 2) return 0;
if (lld.quot != 3 || lld.rem != 2) return 0;
+ if (imd.quot != 3 || imd.rem != 2) return 0;
+ if (memalignment(NULL) != 0) return 0;
+ if (memalignment(aligned) < 1) return 0;
qsort(values, 6, sizeof(values[0]), cmp_int);
for (int i = 0; i < 6; i++) {
@@ -107,6 +136,37 @@ static int stdlib_ok(void) {
return 1;
}
+static int c23_bits_ok(void) {
+ int out;
+
+ if (CHAR_WIDTH != 8 || INT_WIDTH != 32 || INT64_WIDTH != 64) return 0;
+ if (stdc_leading_zeros_uc((unsigned char)0x10u) != 3) return 0;
+ if (stdc_trailing_zeros_ui(0x20u) != 5) return 0;
+ if (stdc_count_ones_ui(0xb1u) != 4) return 0;
+ if (stdc_count_zeros_uc((unsigned char)0xf0u) != 4) return 0;
+ if (!stdc_has_single_bit_ui(0x8000u)) return 0;
+ if (stdc_has_single_bit_ui(0x8001u)) return 0;
+ if (stdc_bit_width_ui(0x80u) != 8) return 0;
+ if (stdc_bit_floor_ui(130u) != 128u) return 0;
+ if (stdc_bit_ceil_ui(129u) != 256u) return 0;
+ if (stdc_first_leading_one_uc((unsigned char)0x10u) != 4) return 0;
+ if (stdc_first_trailing_one_ui(0x10u) != 5) return 0;
+ if (stdc_first_leading_zero_uc((unsigned char)0xefu) != 4) return 0;
+ if (stdc_first_trailing_zero_ui(0xefu) != 5) return 0;
+ if (stdc_leading_ones((unsigned char)0xf0u) != 4) return 0;
+ if (stdc_trailing_ones((unsigned int)0x0fu) != 4) return 0;
+ if (stdc_count_zeros((unsigned char)0xf0u) != 4) return 0;
+ if (stdc_bit_width((unsigned int)0x80u) != 8) return 0;
+ if (stdc_bit_floor((unsigned int)130u) != 128u) return 0;
+ if (stdc_bit_ceil((unsigned int)129u) != 256u) return 0;
+
+ if (ckd_add(&out, INT_MAX, 1) != true) return 0;
+ if (ckd_add(&out, 10, 20) != false || out != 30) return 0;
+ if (ckd_sub(&out, INT_MIN, 1) != true) return 0;
+ if (ckd_mul(&out, 7, 6) != false || out != 42) return 0;
+ return 1;
+}
+
static int stdio_ok(void) {
char buf[64];
int rc;
@@ -114,6 +174,10 @@ static int stdio_ok(void) {
rc = snprintf(buf, sizeof(buf), "%s:%d:%04x:%c", "id", -7, 26, '!');
if (rc != 12 || strcmp(buf, "id:-7:001a:!") != 0) return 31;
+ rc = snprintf(buf, sizeof(buf), "%" PRIdMAX "/%" PRIuMAX, (intmax_t)-9,
+ (uintmax_t)10);
+ if (rc != 5 || strcmp(buf, "-9/10") != 0) return 30;
+
rc = snprintf(buf, 6, "abcdef");
if (rc != 6 || strcmp(buf, "abcde") != 0) return 32;
@@ -162,6 +226,7 @@ int test_main(void) {
assert(1);
if (!strings_ok()) return 1;
if (!stdlib_ok()) return 2;
+ if (!c23_bits_ok()) return 3;
rc = stdio_ok();
if (rc != 0) return rc;
return 42;
diff --git a/test/rt/smoke.c b/test/rt/smoke.c
@@ -28,6 +28,7 @@
#include <ctype.h>
#include <float.h>
+#include <inttypes.h>
#include <iso646.h>
#include <kit/backtrace.h>
#include <kit/coro.h>
@@ -36,7 +37,9 @@
#include <stdalign.h>
#include <stdarg.h>
#include <stdatomic.h>
+#include <stdbit.h>
#include <stdbool.h>
+#include <stdckdint.h>
#include <stddef.h>
#include <stdint.h>
#include <stdnoreturn.h>
@@ -88,6 +91,13 @@ _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");
+_Static_assert(INT_WIDTH == 32, "C23 width macro");
+_Static_assert(UINTPTR_WIDTH == sizeof(uintptr_t) * CHAR_BIT, "uintptr width");
+_Static_assert(__STDC_VERSION_INTTYPES_H__ == 202311L, "inttypes version");
+_Static_assert(__STDC_VERSION_STDBIT_H__ == 202311L, "stdbit version");
+_Static_assert(__STDC_VERSION_STDCKDINT_H__ == 202311L, "stdckdint version");
+_Static_assert(__STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_LITTLE__,
+ "kit targets little-endian");
/* iso646 substitutions */
_Static_assert((1 and 1) == 1, "and");
@@ -223,6 +233,23 @@ static int kit_ctype_compiles(void) {
tolower('Z') == 'z' && toupper('z') == 'Z';
}
+static int kit_c23_headers_compile(void) {
+ int checked;
+ imaxdiv_t d = imaxdiv((intmax_t)17, (intmax_t)5);
+ if (imaxabs((intmax_t)-3) != (intmax_t)3) return 0;
+ if (d.quot != 3 || d.rem != 2) return 0;
+ if (strtoimax("7", (char**)0, 10) != (intmax_t)7) return 0;
+ if (strtoumax("10", (char**)0, 10) != (uintmax_t)10) return 0;
+ if (stdc_leading_zeros_uc((unsigned char)0x10u) != 3) return 0;
+ if (stdc_trailing_zeros_ui(0x20u) != 5) return 0;
+ if (stdc_count_ones_ui(0xb1u) != 4) return 0;
+ if (!stdc_has_single_bit_ui(0x80u)) return 0;
+ if (stdc_bit_floor_ui(130u) != 128u) return 0;
+ if (stdc_bit_ceil_ui(129u) != 256u) return 0;
+ if (ckd_add(&checked, 40, 2)) return 0;
+ return checked == 42;
+}
+
/* kit/backtrace: the capture/print surface compiles and resolves. Compile-only
-- smoke.c never links against a libkit_rt, so the actual walk never runs. */
static int kit_backtrace_compiles(void) {
@@ -240,5 +267,6 @@ int kit_smoke_ok(void) {
if (0) (void)kit_coro_compiles();
if (0) (void)kit_backtrace_compiles();
if (0) (void)kit_ctype_compiles();
+ if (0) (void)kit_c23_headers_compile();
return sum_n(3, 1, 2, 3) == 6 && kit_atomic_ok();
}