URI: 
       cc2/qbe: Fix post increment and decrement - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit cc00e16d081e5f802f046bc0a40ef597a4af1c0e
   DIR parent 0768762d445cd3850147a54ea6625f72e5c1a8e4
  HTML Author: Zhaoming Luo <zhml@posteo.com>
       Date:   Wed, 24 Jun 2026 09:35:06 +0000
       
       cc2/qbe: Fix post increment and decrement
       
       These operators use their operand as lhs and rhs. Function
       lhs_rhs() calls lhs() and may modify variable 'l'. When the
       operator is pointer dereference or struct/union field access,
       the variable 'l' will be modifed to a pointer type node
       pointing to the value of lhs. After that, in load(), choose
       the QBE load instruction based on the lhs type. Because
       'l' may be modifed to a pointer type node, 'l->type' may be
       different to the lhs type; if it's the case, it may happen
       using an address to a 32 bits value to get a 64 bits value.
       Therefore, 'l->type' should not be used to define the QBE
       load instruction. Use 'r->type' because the value of 'r' is
       not modified, and the type of 'lhs' and 'rhs' are the same,
       otherwise they can't be operands of the same expression.
       
       Also add the tests for this fix.
       
       Co-authored-by: Roberto E. Vargas Caballero <k0ga@shike2.net>
       
       Diffstat:
         M src/cmd/scc-cc/cc2/qbe/cgen.c       |       2 +-
         M tests/cc/execute/.gitignore         |       2 ++
         A tests/cc/execute/0276-array.c       |       7 +++++++
         A tests/cc/execute/0277-struct.c      |      12 ++++++++++++
         M tests/cc/execute/scc-tests.lst      |       2 ++
       
       5 files changed, 24 insertions(+), 1 deletion(-)
       ---
   DIR diff --git a/src/cmd/scc-cc/cc2/qbe/cgen.c b/src/cmd/scc-cc/cc2/qbe/cgen.c
       @@ -482,7 +482,7 @@ assign(Node *np)
                        op = OSUB;
                post_oper:
                        lhs_rhs(&l, &r);
       -                ret = load(&l->type, l);
       +                ret = load(&r->type, l);
                        aux.op = op;
                        aux.left = ret;
                        aux.right = r;
   DIR diff --git a/tests/cc/execute/.gitignore b/tests/cc/execute/.gitignore
       @@ -269,3 +269,5 @@ tmp_*.c
        0273-cpp
        0274-loop
        0275-struct
       +0276-array
       +0277-struct
   DIR diff --git a/tests/cc/execute/0276-array.c b/tests/cc/execute/0276-array.c
       @@ -0,0 +1,7 @@
       +int arr[2] = { 0, 2 };
       +
       +int
       +main(void)
       +{
       +        return arr[0]++;
       +}
   DIR diff --git a/tests/cc/execute/0277-struct.c b/tests/cc/execute/0277-struct.c
       @@ -0,0 +1,12 @@
       +struct S {
       +        int a;
       +        int b;
       +};
       +struct S s = { 0, 1 };
       +int arr[2] = { 0, 1 };
       +
       +int
       +main (void)
       +{
       +        return arr[s.a++];
       +}
   DIR diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst
       @@ -266,3 +266,5 @@
        0273-cpp
        0274-loop
        0275-struct
       +0276-array
       +0277-struct