C chained pointer indexing loses base type
- Type: bug (Track C / C pointer metadata)
- Status: backlog
- Owner: —
- Found / Opened: 2026-06-27, while validating C
main(argc, argv).
Symptom
Direct chained indexing through a multi-level pointer can lose the ultimate base type. This fails even though stepping through an explicit intermediate pointer works:
int main(int argc, char **argv) {
if (argv[1][0] != 'a') return 2;
return 42;
}
Observed with /tmp/cargv_cmp ab xyz:
exit=2
But both probes below work:
int main(int argc, char **argv) { return argv[1][0]; } // exits 97
int main(int argc, char **argv) { char *p = argv[1]; return p[0]; } // exits 97
Likely Cause
The C frontend currently records only the immediate pointed-at type for symbols.
For char **argv, the symbol is represented as pointer-to-pointer, so the first
subscript correctly has pointer stride, but the second subscript no longer knows
that the pointed-at base type is char. The expression is then lowered/tagged as
a pointer-width value in comparison contexts instead of a byte-sized char.
Acceptance
argv[1][0] == 'a'works directly forchar **argv.- Nested pointer indexing preserves both immediate pointer stride and the ultimate scalar/record base type.
- Add a C regression for direct chained indexing through
char **.
Workaround
Assign the intermediate pointer first:
char *p = argv[1];
if (p[0] != 'a') return 2;
Audit
- 2026-06-27 — Still open. Current
compiler/pascal26reproduces the direct chained-index bug: compiling and running theargv[1][0] != 'a'probe withabexits2; the explicitchar *p = argv[1]workaround still works. - 2026-06-27 — Fixed. C pointer declarations now preserve both immediate pointer
element metadata and ultimate base metadata/depth, so
char **argvindexes first with pointer stride and then with char stride. Addedtest/cnested_pointer_b94.ccovering directargv[1][0], localchar **indexing, scalar***p, and struct field access through**.