kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

Bug A — MCEmitter: label NNNN placed twice compiling yyjson at -O0

Status: FIXED. yyjson compiles, links, and runs at both -O0 and -O1 and matches clang. The defect was in the front end, not the emitter: a goto label whose first mention is inside a constant-false (codegen-suppressed) region was assigned c_cg_label_new's suppression sentinel instead of a real CG-label id, so it later aliased the function's first real label and the -O0 native emitter aborted placing that id twice. parse_function_body now keys goto-label allocation off whether the function emits at all (Parser.cur_func_emits), not the momentary suppress depth. Regression: test/parse/cases/6_8_06_01_goto_label_in_dead_branch.c.


Original report (kept for the root-cause record):

Component: the symptom prints from the machine-code emitter (src/arch/*/ MCEmitter label pass), but the root cause is front-end label allocation. Severity: kit cannot compile yyjson at -O0 at all.

Symptom

yyjson.c:9041:1: fatal: MCEmitter: label 6020 placed twice

The line (and the internal label number) move slightly with the input, but it always lands on a fail_*: epilogue label of a large writer function — yyjson_write_single (yyjson.c:8947–9044) or yyjson_write_minify (9053–9216). These functions are big switch bodies whose arms all goto a shared handful of fail_alloc:/fail_type:/fail_num:/fail_str: epilogues (via the return_err macro). The emitter places the same internal label twice — i.e. a basic-block/label-dedup defect when many predecessors branch to one shared, late label in a large function.

Reproduce

make provision-ecosystem          # once (network)
KIT=build/kit
SDK="$(xcrun --sdk macosx --show-sdk-path)"
YY="$(sh scripts/ecosystem.sh srcdir yyjson)"

# Fails at -O0:
$KIT cc -O0 --sysroot "$SDK" -I "$YY" -c "$YY/yyjson.c" -o /tmp/yyjson.o

Notes for digging