motiejus/zig

fork of https://codeberg.org/ziglang/zig
git clone https://git.jakstys.lt/motiejus/zig.git
Log | Tree | Refs | README | LICENSE

commit ffb1a6d9a75a7c8804c0e9db0e23ac54265f447c (tree)
parent 7829be6ee07aba6574fa5035c3d33023b3e23de7
Author: Devin J. Pohly <djpohly@gmail.com>
Date:   Thu, 13 Jun 2024 23:49:29 -0500

translate-c: fix translation of "ptr += uint"

The right-hand side was incorrectly cast to a pointer, since only signed
ints were being interpreted correctly as pointer arithmetic.

Fixes #20285.

Diffstat:
Msrc/translate_c.zig | 3++-
Atest/cases/run_translated_c/compound_assignments_with_pointer_arithmetic.c | 21+++++++++++++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/translate_c.zig b/src/translate_c.zig @@ -3824,8 +3824,9 @@ fn transCreateCompoundAssign( const lhs_qt = getExprQualType(c, lhs); const rhs_qt = getExprQualType(c, rhs); const is_signed = cIsSignedInteger(lhs_qt); + const is_ptr_arithmetic = qualTypeIsPtr(lhs_qt) and cIsInteger(rhs_qt); const is_ptr_op_signed = qualTypeIsPtr(lhs_qt) and cIsSignedInteger(rhs_qt); - const requires_cast = !lhs_qt.eq(rhs_qt) and !is_ptr_op_signed; + const requires_cast = !lhs_qt.eq(rhs_qt) and !is_ptr_arithmetic; if (used == .unused) { // common case diff --git a/test/cases/run_translated_c/compound_assignments_with_pointer_arithmetic.c b/test/cases/run_translated_c/compound_assignments_with_pointer_arithmetic.c @@ -0,0 +1,21 @@ +int main() { + const char *s = "forgreatjustice"; + unsigned int add = 1; + + s += add; + if (*s != 'o') return 1; + + s += 1UL; + if (*s != 'r') return 2; + + const char *s2 = (s += add); + if (*s2 != 'g') return 3; + + s2 -= add; + if (*s2 != 'r') return 4; + + return 0; +} + +// run-translated-c +// c_frontend=clang