From ffb1a6d9a75a7c8804c0e9db0e23ac54265f447c Mon Sep 17 00:00:00 2001 From: "Devin J. Pohly" Date: Thu, 13 Jun 2024 23:49:29 -0500 Subject: [PATCH] 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. --- src/translate_c.zig | 3 ++- ...ound_assignments_with_pointer_arithmetic.c | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/cases/run_translated_c/compound_assignments_with_pointer_arithmetic.c diff --git a/src/translate_c.zig b/src/translate_c.zig index 148b73955b..8778310751 100644 --- 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 new file mode 100644 index 0000000000..2dea669708 --- /dev/null +++ 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