← board

C: invalid symbol in lea lowering sqlite amalgamation

Symptom

Compiling the sqlite 3.46.0 amalgamation (library_candidates/sqlite/sqlite3.c, fetch via tools/install_lib_candidates.sh sqlite) fails the IR validation pass:

pascal26:22272: error: invalid symbol in lea ()

Raised at ir.inc:296 (the IR_LEA arm of the IR verifier):

IR_LEA:
  if (IRA[i] < 0) or (IRA[i] >= SymCount) then
    Error('invalid symbol in lea');

So some C construct lowers to an IR_LEA whose IRA (symbol index) is out of [0, SymCount) — almost certainly negative / an unresolved-or-placeholder sym.

Ruled out

Position is unreliable

The reported 22272 lands inside a dead #ifdef block (azCompileOpt[]). The verifier runs after lowering, so the printed line is just the last-set counter, not the offending construct. Do not trust it.

Next step (diagnosis plan)

  1. Instrument ir.inc:296 to print i, IRA[i], SymCount, and the current proc/node context instead of bailing — recompile sqlite, capture the bad sym value (negative? a sentinel like -1? a specific large index?).
  2. From the value, find the emit site: grep the C→IR lowering for IR_LEA emission where the sym can be unresolved (extern not yet bound? address-of a not-yet-allocated global? a function/label sym used as a data sym?).
  3. Reduce to a minimal C repro once the construct is known; add to test/.

Acceptance

Log

Diagnosis (2026-06-27, session 2)

Instrumented the IR_LEA verifier and IRLowerAddress (reverted after). Chain:

Not yet reduced

Isolated repros that did NOT trigger it: plain string-concat element ({"A=" "B"}), stringify of a numeric macro, a 0/null element in a char*[], &global[const]. So the trigger is specific to pxx's expansion of a surviving azCompileOpt entry. Next probe: dump pxx's preprocessed view of that array (no -E/preprocess-dump flag exists — add one, or instrument cpreproc), or log IRLowerAddress's caller to capture the parent expression that wraps an int literal in an address-of.

Log

REJECTED (2026-06-27, session 3) — not a bug, missing -Ilib/crtl/include

Root cause: sqlite was compiled without -Ilib/crtl/include, so #include <stdarg.h> resolved to the system header whose va_arg does not map to pxx's __builtin_va_arg desugar. That is the exact shape of the already-fixed [[track-c-va-arg-nonint-lea]] (va_arg -> *(T*)__pxx_va_arg(&ap), IRLowerAddress of an int-literal). The Makefile C tests all pass -Ilib/crtl/ include; my manual sqlite invocations did not.

With -Ilib/crtl/include:

So this ticket is rejected (operator error). The real findings from the investigation are kept: [[bug-c-addr-of-global-array-element-const-index-wrong-offset]], [[bug-c-sizeof-array-yields-element-size]], the --dump-cpp flag, and the new function-pointer-struct-field wall (see [[feature-c-desktop-lua-sqlite-path]] M5).

LESSON: C compiles need -Ilib/crtl/include for pxx's crtl headers. Consider auto-adding it for .c inputs (filed as a note in the M5 log).