← board

C frontend: partial multi-dim array index rejected ("wrong number of array subscripts")

Repro (minimal)

static int g[2][9][7];
int main(void) {
  int (*row)[7] = g[1][3];   /* partial index: 2 of 3 dims -> int(*)[7] */
  row[0][2] = 77;
  return g[1][3][2];         /* 77 */
}

A full index (g[i][j][k], all 3 dims) works fine; so does a single g[i]. Only a partial multi-index (more than one subscript but fewer than the declared rank) is rejected. The csmith program hit the same error path in a larger expression.

Root

cparser.inc:2374-2394 flattens chained subscripts on a known multi-dim array to one row-major AN_INDEX. It parses subscripts while (CurTok = '[') and (nIdx < NDInfoNDims) then hard-requires nIdx = NDInfoNDims (line 2388), erroring otherwise. A partial index (nIdx < NDInfoNDims) is valid C — it decays to a pointer to the remaining sub-array (g[1][3] on int[2][9][7] is int(*)[7]) — but this branch only models the full-rank element access.

Fix direction

On a partial index (nIdx < NDInfoNDims), instead of erroring, produce the sub-array pointer: base + flatidx(nIdx) * stride(remaining dims), typed as a pointer-to-array of the remaining shape, so subsequent [...] / deref work. The existing BuildFlatNDIndex computes the row-major offset for the supplied subscripts; the remaining stride is the product of the un-indexed dimension spans. Element type / rank bookkeeping must reflect the residual dimensions.

Acceptance

Note

Found by tools/csmith_fuzz.py (pxx vs gcc). 24/30 seeds agreed; this was the lone PXX_COMPILE_FAIL. Reproduces from the seed exactly.

Log