URI:
       cc1: Emit hidden variables for compound literals - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit b27864c02e4c06be0bac3a0c673d85bb3a281b71
   DIR parent 76a7e8501aac08ca649752263c991b03a3a73d7b
  HTML 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:
         M src/cmd/scc-cc/cc1/cc1.h            |       1 +
         M src/cmd/scc-cc/cc1/expr.c           |       7 +++++--
         M src/cmd/scc-cc/cc1/init.c           |      19 +++++++++++++------
         M tests/cc/execute/0177-literal.c     |      18 ++++++++++++++----
         A tests/cc/execute/0252-literal.c     |      31 +++++++++++++++++++++++++++++++
         M tests/cc/execute/scc-tests.lst      |       5 +++--
       
       6 files changed, 67 insertions(+), 14 deletions(-)
       ---
   DIR 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);
   DIR 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:
   DIR 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);
                }
        }
   DIR 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});
        }
   DIR 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});
       +}
   DIR 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