commit 5a5db977a8a65fc1cb3656ef55cd579496a377bf
parent 67cf8a126f8a96736a156e5edf2164a1669c9544
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date: Sun, 29 Mar 2026 16:01:11 +0200
cc1: Accept strings in initialization lists
They have to be handled in a different way because a string
initializes the full char array and it does not work well
with the function mkcompose().
Diffstat:
6 files changed, 54 insertions(+), 23 deletions(-)
diff --git a/src/cmd/scc-cc/cc1/cc1.h b/src/cmd/scc-cc/cc1/cc1.h
@@ -508,9 +508,7 @@ int cmpnode(Node *np, unsigned long long val);
int power2node(Node *, int *);
/* init.c */
-void initializer(Symbol *sym, Type *tp);
-Node *initlist(Type *tp);
-Symbol *autoinit(Symbol *, Type *, Node *);
+void initializer(Symbol *);
/* cpp.c */
void icpp(void);
diff --git a/src/cmd/scc-cc/cc1/decl.c b/src/cmd/scc-cc/cc1/decl.c
@@ -312,7 +312,7 @@ identifier(struct decl *dcl)
}
if (accept('='))
- initializer(sym, sym->type);
+ initializer(sym);
if (!(sym->flags & (SGLOBAL|SEXTERN)) && tp->op != FTN)
sym->flags |= SDEFINED;
if (sym->token == IDEN && tp->op != FTN)
diff --git a/src/cmd/scc-cc/cc1/expr.c b/src/cmd/scc-cc/cc1/expr.c
@@ -972,9 +972,13 @@ cast(void)
expect(')');
if (yytoken == '{') {
- np = initlist(tp);
- np = varnode(autoinit(NULL, tp, np));
- return decay(np);
+ Symbol *sym = newsym(NS_IDEN, NULL);
+ sym->id = newid();
+ sym->type = tp;
+ sym->flags |= SAUTO;
+ initializer(sym);
+
+ return decay(varnode(sym));
}
switch (tp->op) {
diff --git a/src/cmd/scc-cc/cc1/init.c b/src/cmd/scc-cc/cc1/init.c
@@ -123,6 +123,8 @@ str2ary(Type *tp)
return np;
}
+static Node *initlist(Type *);
+
static Node *
initialize(Type *tp, int inlist)
{
@@ -226,16 +228,26 @@ initlist_helper(Type *tp)
{
Init in;
Node *np;
- Type *curtp;
+ Type *curtp, *btp;
int braces, scalar, toomany, outbound;
long long nelem = tp->n.elem;
- init(&in);
braces = scalar = toomany = 0;
if (accept('{'))
braces = 1;
+ if (yytoken == STRING && tp->op == ARY) {
+ btp = tp->type;
+ if (btp == chartype || btp == uchartype || btp == schartype) {
+ np = str2ary(tp);
+ if (braces)
+ expect('}');
+ return np;
+ }
+ }
+
+ init(&in);
for (;;) {
curtp = inttype;
switch (yytoken) {
@@ -326,7 +338,7 @@ new_desig:
return mkcompound(&in, tp);
}
-Node *
+static Node *
initlist(Type *tp)
{
Node *np;
@@ -454,18 +466,12 @@ emitstrings(Node *np)
emitstrings(np->right);
}
-Symbol *
-autoinit(Symbol *sym, Type *tp, Node *np)
+static void
+autoinit(Symbol *sym, Node *np)
{
unsigned long long a;
Symbol *hidden;
-
- if (!sym) {
- sym = newsym(NS_IDEN, NULL);
- sym->id = newid();
- sym->type = tp;
- sym->flags |= SAUTO;
- }
+ Type *tp = np->type;
repeat:
switch (tp->op) {
@@ -502,14 +508,13 @@ repeat:
emit(OEXPR, np);
break;
}
-
- return sym;
}
void
-initializer(Symbol *sym, Type *tp)
+initializer(Symbol *sym)
{
Node *np;
+ Type *tp = sym->type;
int flags = sym->flags;
if (tp->op == FTN) {
@@ -535,6 +540,6 @@ initializer(Symbol *sym, Type *tp)
errorp("'%s' has both '%s' and initializer",
sym->name, (flags&SEXTERN) ? "extern" : "typedef");
} else {
- autoinit(sym, np->type, np);
+ autoinit(sym, np);
}
}
diff --git a/tests/cc/execute/0255-init.c b/tests/cc/execute/0255-init.c
@@ -0,0 +1,23 @@
+#define SIZ 6
+
+int test(char *);
+
+int
+test(char *s)
+{
+ if (s[0] != 'a')
+ return 1;
+ if (s[1] != 'b')
+ return 2;
+ if (s[2] != 'c')
+ return 3;
+ if (s[3] != '\0')
+ return 4;
+ return 0;
+}
+
+int
+main(void)
+{
+ return test((char[SIZ]) {"abc"});
+}
diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst
@@ -245,3 +245,4 @@
0252-literal.c
0253-maxconst.c
0254-litchar.c
+0255-init.c