commit 0cd6aa8cf9ff39a34a3e4de9f2508aaa7fb6f6ed
parent bbea27bd4c29996f1dc1ebc94d3ab798e4f9e731
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 29 Apr 2026 12:51:28 -0700
cc: stdarg patch to builtins
Diffstat:
4 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/cc/headers/stdarg.h b/cc/headers/stdarg.h
@@ -1,22 +0,0 @@
-/* lispcc-bundled <stdarg.h>. Per CC.md §Standard library expectations,
- * the pre-flatten step splices this in for any source that
- * `#include`s <stdarg.h>; the compiler proper rejects #include.
- *
- * va_list is a single pointer. va_start, va_arg, va_end are macros
- * around the __builtin_va_* names recognized by the parser. See
- * cc/parse.scm parse-builtin-va-{start,arg,end}.
- *
- * Limit (cc/cg.scm cg-fn-begin/v): the incoming-arg window covers
- * indices 0..15 (a-regs for 0..3, LDARG for 4..15). Calls with more
- * than 15 variadic args after the named ones won't see them. */
-
-#ifndef _STDARG_H
-#define _STDARG_H
-
-typedef char *va_list;
-
-#define va_start(ap, last) __builtin_va_start((ap), (last))
-#define va_arg(ap, T) __builtin_va_arg((ap), T)
-#define va_end(ap) __builtin_va_end((ap))
-
-#endif
diff --git a/scripts/libc-flatten.sh b/scripts/libc-flatten.sh
@@ -64,6 +64,7 @@ cp -R "$VENDOR/." "$STAGE/"
# symlink so the unprefixed `arch/...` includes resolve.
ln -sfn "linux/$MES_ARCH" "$STAGE/include/arch"
+
# --- (2) patches ------------------------------------------------------
# Same literal-block replacer as stage1-flatten.sh apply_simple_patch.
apply_simple_patch() {
@@ -120,6 +121,17 @@ apply_simple_patch \
"$STAGE/mes/ntoab.c" \
"$PATCHES/ntoab-inline-defined.before" \
"$PATCHES/ntoab-inline-defined.after"
+# Route mes's va_start/va_arg/va_end macros through cc.scm's
+# __builtin_va_* (parser-recognized in cc/cc.scm parse-builtin-va-*).
+# The original macros lower as raw C expressions; cc.scm's general
+# expression path mishandles them subtly (cc-libc/05 prints the format
+# char instead of the spilled int). The builtin path is the same one
+# tests/cc/131-vararg-mixed exercises end-to-end for printf-shaped
+# two-frame va_list forwarding.
+apply_simple_patch \
+ "$STAGE/include/stdarg.h" \
+ "$PATCHES/stdarg-builtin.before" \
+ "$PATCHES/stdarg-builtin.after"
# --- (3) flatten via host preprocessor --------------------------------
HOST_CC=${HOST_CC:-cc}
diff --git a/vendor/mes-libc/patches/stdarg-builtin.after b/vendor/mes-libc/patches/stdarg-builtin.after
@@ -0,0 +1,12 @@
+/* Routed through cc.scm's __builtin_va_* parser-recognized names so
+ * va_start/va_arg/va_end go through cc/cc.scm cg-va-{start,arg,end}.
+ * The original mes macros lower as raw C expressions; cc.scm's
+ * general expression path mishandles them (see cc-libc/05). The
+ * builtin path is exercised by tests/cc/131-vararg-mixed for the
+ * printf -> vprintf -> vfprintf two-frame forwarding shape. */
+typedef char *va_list;
+#define va_start(ap, last) __builtin_va_start((ap), (last))
+#define va_arg(ap, type) __builtin_va_arg((ap), type)
+#define va_arg8(ap, type) __builtin_va_arg((ap), type)
+#define va_end(ap) __builtin_va_end((ap))
+#define va_copy(dest, src) (dest) = (src)
diff --git a/vendor/mes-libc/patches/stdarg-builtin.before b/vendor/mes-libc/patches/stdarg-builtin.before
@@ -0,0 +1,7 @@
+typedef char *va_list;
+#define va_start(ap, last) (void)((ap) = (char*)(&(last)) + sizeof (void*))
+#define va_arg(ap, type) (type)(((long*)((ap) = ((ap) + sizeof (void*))))[-1])
+#define va_align(ap, alignment) ((char*)((((unsigned long) (ap)) + (alignment) - 1) &~ ((alignment) - 1)))
+#define va_arg8(ap, type) (type)(((double*)((ap) = (va_align((ap), 8) + sizeof(double))))[-1])
+#define va_end(ap) (void)((ap) = 0)
+#define va_copy(dest, src) dest = src