https://gcc.gnu.org/g:f2e98084792821c3849074867d5b007c49028854
commit r14-10488-gf2e98084792821c3849074867d5b007c49028854 Author: Jan Hubicka <hubi...@ucw.cz> Date: Mon Jul 22 18:05:26 2024 +0200 Fix accounting of offsets in unadjusted_ptr_and_unit_offset unadjusted_ptr_and_unit_offset accidentally throws away the offset computed by get_addr_base_and_unit_offset. Instead of passing extra_offset it passes offset. PR ipa/114207 gcc/ChangeLog: * ipa-prop.cc (unadjusted_ptr_and_unit_offset): Fix accounting of offsets in ADDR_EXPR. gcc/testsuite/ChangeLog: * gcc.c-torture/execute/pr114207.c: New test. (cherry picked from commit 391f46f10b0586c074014de82efe76787739bb0c) Diff: --- gcc/ipa-prop.cc | 4 ++-- gcc/testsuite/gcc.c-torture/execute/pr114207.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 374e998aa64b..99d4c33e8fdc 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -1370,9 +1370,9 @@ unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret) { if (TREE_CODE (op) == ADDR_EXPR) { - poly_int64 extra_offset = 0; + poly_int64 extra_offset; tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0), - &offset); + &extra_offset); if (!base) { base = get_base_address (TREE_OPERAND (op, 0)); diff --git a/gcc/testsuite/gcc.c-torture/execute/pr114207.c b/gcc/testsuite/gcc.c-torture/execute/pr114207.c new file mode 100644 index 000000000000..052fa85e9fc6 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr114207.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include <stdint.h> + +struct S { + int a, b; +}; + +__attribute__((noinline)) +void foo (struct S *s) { + struct S ss = (struct S) { + .a = s->b, + .b = s->a + }; + *s = ss; +} + +int main() { + struct S s = {6, 12}; + foo(&s); + if (s.a != 12 || s.b != 6) + __builtin_abort (); + return 0; +}