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:
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