Against trunk [r16743]. One patch, independent of anything else I have open.
A compound literal is parsed into a temporary symbol marked iscomplit, and gatherImplicitVariables() adds that symbol to the declaration list of the enclosing block. It walks the function body, so it finds the literal in a statement:
struct s v; v = (struct s) {1, 2, 3}; /* worked */
but not in the initializer of a declaration:
struct s v = (struct s) {1, 2, 3}; /* did not */
There the literal is still in sym->ival — an initializer list, not a tree — and gatherAutoInit() only turns it into a tree later, after gatherImplicitVariables() has run and after allocVariables() has assigned storage. The temporary is therefore never declared and never allocated, so it has no rname:
ld hl, # with an empty symbol, which the assembler rejects — <q> missing or improper operators;&(struct s){...} and char *p = (char[]){...} in a declaration are affected the same way. Assignment-RHS and static locals are not, which is why support/regression/tests/compound-literal.c did not catch it — it covers only those two forms. The patch extends it.
The fix attaches and allocates the temporary in gatherAutoInit(), once the initializer has become a tree.
It is prepended to the initializer that reads it, not hoisted to the top of the block. Hoisting would be wrong:
char x = 5;
struct s v = (struct s){x, 2, 3}; /* would read x before x = 5 */
gatherAutoInit() already walks declarations in order, so placing it per symbol preserves the ordering. The test covers two literals cross-referencing two earlier locals, and a literal in a nested block, with volatile seeds so constant folding cannot mask a mistake.
static-local paths, which already worked.compound-literal.c does not link on ucz80 and fails 17 of 26 cases on a target whose assembler accepts the empty operand. Post-fix, 0 of 26 on both.
Very nice. As the author of the compound literal functionality, I felt competent enough to review this one, quickly. (Never found the time to fix it myself, unfortunately)
Your patch is now in [r16747] with one very minor change: I had to comment out a union-related line in the test case. It is quite possible that one of your patches in [patches:#508] would have taken care of the underlying problem.
Related
Commit: [r16747]
Patches: #508