commit 894503f54469181fc620f67445d7fdec5e33a26e
parent 7619cde3e256a2fe323e1d029c0c0ec999b8f986
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 25 May 2026 13:44:20 -0700
cc: honor -x language for stdin
Diffstat:
2 files changed, 43 insertions(+), 6 deletions(-)
diff --git a/driver/cc.c b/driver/cc.c
@@ -31,7 +31,7 @@
* -e symbol -T script.ld
* -static -pie -no-pie
* -l name -L dir
- * -x c (no-op; rejected for any other language)
+ * -x c|asm|s|asm-cpp|S|wasm|wat
* - (stdin source)
* .c/.cc -> source; .o/.obj -> object inputs; .a -> archive inputs.
*
@@ -798,7 +798,7 @@ static int cc_run_probe(CcOptions* o) {
return 0;
}
-static int cc_record_stdin(CcOptions* o) {
+static int cc_record_stdin(CcOptions* o, int forced_lang) {
CfreeSourceInput* in;
if (o->stdin_buf) {
driver_errf(CC_TOOL, "'-' (stdin) may appear at most once");
@@ -812,7 +812,7 @@ static int cc_record_stdin(CcOptions* o) {
in->name = CFREE_SLICE_LIT("<stdin>");
in->bytes.data = o->stdin_buf;
in->bytes.len = o->stdin_size;
- in->lang = CFREE_LANG_C;
+ in->lang = forced_lang >= 0 ? (CfreeLanguage)forced_lang : CFREE_LANG_C;
cc_push_link_item(o, CC_LINK_SOURCE_MEMORY, o->nsource_memory - 1u);
return 0;
}
@@ -830,7 +830,7 @@ static CfreeLanguage cc_resolve_lang(CfreeCompiler* c, const char* path,
static int cc_classify_positional(CcOptions* o, const char* a,
int forced_lang) {
- if (driver_streq(a, "-")) return cc_record_stdin(o);
+ if (driver_streq(a, "-")) return cc_record_stdin(o, forced_lang);
if (forced_lang >= 0 || cc_is_c_source(a)) {
o->source_langs[o->nsource_files] =
forced_lang >= 0 ? (CfreeLanguage)forced_lang : CC_LANG_AUTO;
@@ -1467,11 +1467,18 @@ static int cc_parse(int argc, char** argv, CcOptions* o) {
forced_lang = CFREE_LANG_C;
continue;
}
- if (driver_streq(argv[i], "assembler") ||
- driver_streq(argv[i], "assembler-with-cpp")) {
+ if (driver_streq(argv[i], "asm") || driver_streq(argv[i], "s")) {
forced_lang = CFREE_LANG_ASM;
continue;
}
+ if (driver_streq(argv[i], "asm-cpp") || driver_streq(argv[i], "S")) {
+ forced_lang = CFREE_LANG_ASM;
+ continue;
+ }
+ if (driver_streq(argv[i], "wasm") || driver_streq(argv[i], "wat")) {
+ forced_lang = CFREE_LANG_WASM;
+ continue;
+ }
{
driver_errf(CC_TOOL, "unsupported -x language: %.*s",
CFREE_SLICE_ARG(cfree_slice_cstr(argv[i])));
diff --git a/test/driver/run.sh b/test/driver/run.sh
@@ -92,6 +92,36 @@ else
fail=$((fail + 1))
fi
+for xlang in asm s asm-cpp S; do
+ if printf '.globl asm_stdin\nasm_stdin:\n ret\n' |
+ "$CFREE" cc -target x86_64-linux -x "$xlang" -c - \
+ -o "$work/stdin-$xlang.o" \
+ > "$work/stdin-$xlang.out" 2> "$work/stdin-$xlang.err" &&
+ [ -f "$work/stdin-$xlang.o" ]; then
+ printf 'PASS %s\n' "cc-stdin-x-$xlang"
+ pass=$((pass + 1))
+ else
+ printf 'FAIL %s\n' "cc-stdin-x-$xlang"
+ sed 's/^/ | /' "$work/stdin-$xlang.err"
+ fail=$((fail + 1))
+ fi
+done
+
+for xlang in wasm wat; do
+ if printf '(module (func (export "test_main") (result i32) i32.const 0))\n' |
+ "$CFREE" cc --emit=c -x "$xlang" - \
+ -o "$work/stdin-$xlang.c" \
+ > "$work/stdin-$xlang.out" 2> "$work/stdin-$xlang.err" &&
+ [ -s "$work/stdin-$xlang.c" ]; then
+ printf 'PASS %s\n' "cc-stdin-x-$xlang"
+ pass=$((pass + 1))
+ else
+ printf 'FAIL %s\n' "cc-stdin-x-$xlang"
+ sed 's/^/ | /' "$work/stdin-$xlang.err"
+ fail=$((fail + 1))
+ fi
+done
+
cat > "$work/partial-main.c" <<'SRC'
int foo(void);
int _start(void) { return foo(); }