scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit b27864c02e4c06be0bac3a0c673d85bb3a281b71
parent 76a7e8501aac08ca649752263c991b03a3a73d7b
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Thu, 26 Mar 2026 12:11:27 +0100

cc1: Emit hidden variables for compound literals

Compound literals are just hidden local auto variables and we can reuse
the autoinit() function to emit them.

Diffstat:
Msrc/cmd/scc-cc/cc1/cc1.h | 1+
Msrc/cmd/scc-cc/cc1/expr.c | 7+++++--
Msrc/cmd/scc-cc/cc1/init.c | 19+++++++++++++------
Mtests/cc/execute/0177-literal.c | 18++++++++++++++----
Atests/cc/execute/0252-literal.c | 31+++++++++++++++++++++++++++++++
Mtests/cc/execute/scc-tests.lst | 5+++--
6 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h @@ -510,6 +510,7 @@ int power2node(Node *, int *); /* init.c */ void initializer(Symbol *sym, Type *tp); Node *initlist(Type *tp); +Symbol *autoinit(Symbol *, Type *, Node *); /* cpp.c */ void icpp(void); diff --git a/src/cmd/scc-cc/cc1/expr.c b/src/cmd/scc-cc/cc1/expr.c @@ -971,8 +971,11 @@ cast(void) tp = typename(); expect(')'); - if (yytoken == '{') - return decay(initlist(tp)); + if (yytoken == '{') { + np = initlist(tp); + np = varnode(autoinit(NULL, tp, np)); + return decay(np); + } switch (tp->op) { case ARY: diff --git a/src/cmd/scc-cc/cc1/init.c b/src/cmd/scc-cc/cc1/init.c @@ -454,12 +454,18 @@ emitstrings(Node *np) emitstrings(np->right); } -static void -autoinit(Symbol *sym, Node *np) +Symbol * +autoinit(Symbol *sym, Type *tp, Node *np) { unsigned long long a; Symbol *hidden; - Type *tp = sym->type; + + if (!sym) { + sym = newsym(NS_IDEN, NULL); + sym->id = newid(); + sym->type = tp; + sym->flags |= SAUTO; + } repeat: switch (tp->op) { @@ -479,8 +485,7 @@ repeat: emitstrings(np); emit(ODECL, sym); autocomp(sym, np, np->type, &a); - return; - + break; } hidden = newsym(NS_IDEN, NULL); hidden->id = newid(); @@ -497,6 +502,8 @@ repeat: emit(OEXPR, np); break; } + + return sym; } void @@ -528,6 +535,6 @@ initializer(Symbol *sym, Type *tp) errorp("'%s' has both '%s' and initializer", sym->name, (flags&SEXTERN) ? "extern" : "typedef"); } else { - autoinit(sym, np); + autoinit(sym, np->type, np); } } diff --git a/tests/cc/execute/0177-literal.c b/tests/cc/execute/0177-literal.c @@ -1,9 +1,19 @@ -int boo(int *p) +int +cmp(int *v) { - return (p[1] == 2) ? 0 : 1; + if (v[0] != 1) + return 1; + if (v[1] != 2) + return 2; + if (v[2] != 3) + return 3; + if (v[3] != 4) + return 4; + return 0; } -int main() +int +main(void) { - return boo((int[]) {0, 2}); + return cmp((int []) {1, 2, 3, 4}); } diff --git a/tests/cc/execute/0252-literal.c b/tests/cc/execute/0252-literal.c @@ -0,0 +1,31 @@ +int +cmp(int *v) +{ + if (v[0] != 1) + return 1; + if (v[1] != 2) + return 2; + if (v[2] != 3) + return 3; + if (v[3] != 4) + return 4; + if (v[4] != 69) + return 5; + return 0; +} + +int +set(int *a) +{ + *a = 69; + return 1; +} + +int +main(void) +{ + int a; + + set(&a); + return cmp((int []) {1, 2, 3, 4, a}); +} diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -167,7 +167,7 @@ 0174-decay.c 0175-defined.c 0176-macro.c -0177-literal.c [TODO] +0177-literal.c 0178-include.c 0179-sizeof.c 0180-incomplete.c @@ -203,7 +203,7 @@ 0210-flexible.c 0211-enum.c 0212-krtypes.c -0213-decay.c [TODO] +0213-decay.c 0214-va_copy.c 0215-ret_struct.c 0216-initialize.c @@ -242,3 +242,4 @@ 0249-mod.c 0250-div.c 0251-mul.c +0252-literal.c