scc

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

commit cc00e16d081e5f802f046bc0a40ef597a4af1c0e
parent 0768762d445cd3850147a54ea6625f72e5c1a8e4
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:
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 2+-
Mtests/cc/execute/.gitignore | 2++
Atests/cc/execute/0276-array.c | 7+++++++
Atests/cc/execute/0277-struct.c | 12++++++++++++
Mtests/cc/execute/scc-tests.lst | 2++
5 files changed, 24 insertions(+), 1 deletion(-)

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; 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 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]++; +} 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++]; +} 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