scc

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

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:
Msrc/cmd/scc-cc/cc1/cc1.h | 4+---
Msrc/cmd/scc-cc/cc1/decl.c | 2+-
Msrc/cmd/scc-cc/cc1/expr.c | 10+++++++---
Msrc/cmd/scc-cc/cc1/init.c | 37+++++++++++++++++++++----------------
Atests/cc/execute/0255-init.c | 23+++++++++++++++++++++++
Mtests/cc/execute/scc-tests.lst | 1+
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