commit 549a5f48f3b58a04b3a7784d5c76ee303a9b8962
parent 71fc4b9777dfcce9ddeb91fda7bf0f95f3059cdf
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 30 Apr 2026 09:50:32 -0700
tests/cc-pp: expand to cover stdarg shape
Diffstat:
6 files changed, 105 insertions(+), 0 deletions(-)
diff --git a/tests/cc-pp/40-ifdef-active-typedef-fnmacro.c b/tests/cc-pp/40-ifdef-active-typedef-fnmacro.c
@@ -0,0 +1,8 @@
+#define CCSCM 1
+#ifdef CCSCM
+typedef char *T;
+#define M(x) (x)
+#endif
+
+T a;
+int x = M(0);
diff --git a/tests/cc-pp/40-ifdef-active-typedef-fnmacro.expected-toks b/tests/cc-pp/40-ifdef-active-typedef-fnmacro.expected-toks
@@ -0,0 +1,16 @@
+(KW typedef "40-ifdef-active-typedef-fnmacro.c" 3 1)
+(KW char "40-ifdef-active-typedef-fnmacro.c" 3 9)
+(PUNCT star "40-ifdef-active-typedef-fnmacro.c" 3 14)
+(IDENT "T" "40-ifdef-active-typedef-fnmacro.c" 3 15)
+(PUNCT semi "40-ifdef-active-typedef-fnmacro.c" 3 16)
+(IDENT "T" "40-ifdef-active-typedef-fnmacro.c" 7 1)
+(IDENT "a" "40-ifdef-active-typedef-fnmacro.c" 7 3)
+(PUNCT semi "40-ifdef-active-typedef-fnmacro.c" 7 4)
+(KW int "40-ifdef-active-typedef-fnmacro.c" 8 1)
+(IDENT "x" "40-ifdef-active-typedef-fnmacro.c" 8 5)
+(PUNCT assign "40-ifdef-active-typedef-fnmacro.c" 8 7)
+(PUNCT lparen "40-ifdef-active-typedef-fnmacro.c" 4 14)
+(INT 0 "40-ifdef-active-typedef-fnmacro.c" 8 11)
+(PUNCT rparen "40-ifdef-active-typedef-fnmacro.c" 4 16)
+(PUNCT semi "40-ifdef-active-typedef-fnmacro.c" 8 13)
+(EOF #f "40-ifdef-active-typedef-fnmacro.c" 9 1)
diff --git a/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.c b/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.c
@@ -0,0 +1,10 @@
+#define CCSCM 1
+#ifndef CCSCM
+extern int unreachable;
+#else
+typedef char *T;
+#define M(x) (x)
+#endif
+
+T a;
+int x = M(0);
diff --git a/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.expected-toks b/tests/cc-pp/41-ifndef-defined-else-typedef-fnmacro.expected-toks
@@ -0,0 +1,16 @@
+(KW typedef "41-ifndef-defined-else-typedef-fnmacro.c" 5 1)
+(KW char "41-ifndef-defined-else-typedef-fnmacro.c" 5 9)
+(PUNCT star "41-ifndef-defined-else-typedef-fnmacro.c" 5 14)
+(IDENT "T" "41-ifndef-defined-else-typedef-fnmacro.c" 5 15)
+(PUNCT semi "41-ifndef-defined-else-typedef-fnmacro.c" 5 16)
+(IDENT "T" "41-ifndef-defined-else-typedef-fnmacro.c" 9 1)
+(IDENT "a" "41-ifndef-defined-else-typedef-fnmacro.c" 9 3)
+(PUNCT semi "41-ifndef-defined-else-typedef-fnmacro.c" 9 4)
+(KW int "41-ifndef-defined-else-typedef-fnmacro.c" 10 1)
+(IDENT "x" "41-ifndef-defined-else-typedef-fnmacro.c" 10 5)
+(PUNCT assign "41-ifndef-defined-else-typedef-fnmacro.c" 10 7)
+(PUNCT lparen "41-ifndef-defined-else-typedef-fnmacro.c" 6 14)
+(INT 0 "41-ifndef-defined-else-typedef-fnmacro.c" 10 11)
+(PUNCT rparen "41-ifndef-defined-else-typedef-fnmacro.c" 6 16)
+(PUNCT semi "41-ifndef-defined-else-typedef-fnmacro.c" 10 13)
+(EOF #f "41-ifndef-defined-else-typedef-fnmacro.c" 11 1)
diff --git a/tests/cc-pp/42-ccscm-stdarg-gate.expected-exit b/tests/cc-pp/42-ccscm-stdarg-gate.expected-exit
@@ -0,0 +1 @@
+0
diff --git a/tests/cc-pp/42-ccscm-stdarg-gate.scm b/tests/cc-pp/42-ccscm-stdarg-gate.scm
@@ -0,0 +1,54 @@
+;; tests/cc-pp/42-ccscm-stdarg-gate.scm
+;;
+;; cc.scm pre-defines CCSCM as an empty object macro so test fixtures
+;; can wrap their stdarg.h include in `#ifndef CCSCM ... #else ... #endif`
+;; and route around #include (which cc.scm rejects). This test pins
+;; that contract: with CCSCM in the initial-defines table, the #include
+;; in the then-branch is never processed, the else branch's typedef
+;; emits its tokens, and the else branch's function-like macro is
+;; registered and expanded at the call site.
+
+(define src
+ "#ifndef CCSCM\n#include <stdarg.h>\n#else\ntypedef char *va_list;\n#define va_start(ap, n) __builtin_va_start(ap, n)\n#endif\nva_list ap;\nvoid f(int n) { va_start(ap, n); }\n")
+
+(define ccscm (cons "CCSCM" (%macro 'obj '() '())))
+(define toks (lex-tokenize src "src.c"))
+(define out (pp-expand toks (list ccscm)))
+
+;; Helper: fail with a status-encoded reason if `cond` is false.
+(define (must cond status)
+ (if cond #t (sys-exit status)))
+
+;; #include must NOT have been processed (it would have raised die from
+;; %pp-do-include and aborted with status 1 before getting here).
+
+;; Walk `out` and assert: the typedef line is present, ap (va_list ident)
+;; is present, and the va_start expansion landed on __builtin_va_start.
+(define (find-ident name toks)
+ (cond
+ ((null? toks) #f)
+ ((and (eq? (tok-kind (car toks)) 'IDENT)
+ (bv= (tok-value (car toks)) name))
+ toks)
+ (else (find-ident name (cdr toks)))))
+
+(must (find-ident "va_list" out) 11)
+(must (find-ident "ap" out) 12)
+(must (find-ident "f" out) 13)
+(must (find-ident "__builtin_va_start" out) 14)
+
+;; Negative: __builtin_va_start should appear (from the macro body), but
+;; the literal `va_start` identifier should NOT survive expansion at the
+;; call site.
+(define (count-ident name toks)
+ (let loop ((ts toks) (n 0))
+ (cond
+ ((null? ts) n)
+ ((and (eq? (tok-kind (car ts)) 'IDENT)
+ (bv= (tok-value (car ts)) name))
+ (loop (cdr ts) (+ n 1)))
+ (else (loop (cdr ts) n)))))
+
+(must (= (count-ident "va_start" out) 0) 15)
+
+(sys-exit 0)