← board

_Generic on an array loses the element's pointer target and its constness

The differential, gcc -std=c11 against pascal26 on one file

before is the compiler at e4d4f945961e (no array arm at all), after is a7e7f780b782.

controlling expr gcc before after
struct S a[3] struct S * default struct S *
int b[4] int * int int *
char c[5] char * char char *
long L[2] long * long long *
int m[2][3] default int default
int *p[2] int ** int * default
const int ci[2] const int * int int *
struct S one (control) struct S struct S struct S
int scal (control) int int int

The five fixed rows are pinned by test/cgeneric_array_decay.c (wired into test-core). The two open rows are deliberately NOT in that file: a test that asserts a wrong answer teaches the next reader that the wrong answer is intended. They are here instead, with the oracle command, so whoever takes this starts from a measurement.

Repro (the two rows alone):

#include <stdio.h>
int main(void){
  int *p[2]; const int ci[2];
  puts(_Generic(p,  int **:"i**", int *:"i*", default:"?"));   /* gcc: i**  pxx: ?  */
  puts(_Generic(ci, const int *:"ci*", int *:"i*", default:"?")); /* gcc: ci* pxx: i* */
  (void)p;(void)ci; return 0;
}

Why the array arm cannot answer them

CExprCG's array arm builds the element descriptor from what the SYMBOL carries: Syms[sym].ElemType, Syms[sym].ElemRecName, SymCLongRank[sym], and SymArrNDims/SymArrDimSpan for the inner dimensions. That is enough for a scalar, a record and a multi-dim element, and it is the whole of what the symbol has.

So both are the same shape: a carrier that exists for a scalar symbol and has no array-element twin. That is the thing to fix — a SymElemPtrElemTk / SymElemPtrElemRec / SymElemConst set, threaded where SymElemDynDepth already is — not a special case at the descriptor site.

Ranked 35 deliberately

_Generic on an array of pointers or a const array is rare in real C, and the five common rows are now correct. Ranked by how much real code reaches it, per the compat rule. What raises it is a corpus program selecting wrongly, and the probe above is the thing to re-run then.

What a fix must assert