https://gcc.gnu.org/g:0647498123c253f44cbdd2267ccd18b8da3ec7b4
commit 0647498123c253f44cbdd2267ccd18b8da3ec7b4 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Wed Mar 5 13:08:43 2025 +0100 Correction offset MEM_REF Diff: --- gcc/cgraphunit.cc | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 1 deletion(-) diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index b556626adab5..e7b6e45386bf 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -3152,6 +3152,7 @@ data_value::set_cst_at (unsigned dest_offset, unsigned value_width, enum value_type orig_type = classify (dest_offset, value_width); wide_int dest_mask = wi::shifted_mask (dest_offset, value_width, false, bit_width); + gcc_assert (orig_type != VAL_ADDRESS); if (orig_type != VAL_CONSTANT) { constant_mask |= dest_mask; @@ -3417,6 +3418,15 @@ context_printer::print_at (const data_value & value, tree type, unsigned offset, storage_address *address = value.get_address_at (offset); data_storage &target_storage = address->storage.get (); target_storage.print (*this); + unsigned off = address->offset; + if (off > 0) + { + pp_string (&pp, " + "); + gcc_assert (off % CHAR_BIT == 0); + off /= CHAR_BIT; + pp_decimal_int (&pp, off); + pp_character (&pp, 'B'); + } } break; @@ -3672,6 +3682,7 @@ exec_context::evaluate (tree expr) const storage_address *address = val_ptr.get_address (); gcc_assert (address != nullptr); data_value storage_value = address->storage.get ().get_value (); + unsigned ptr_offset = address->offset; tree offset_bytes = TREE_OPERAND (expr, 1); data_value val_off = evaluate (offset_bytes); @@ -3701,7 +3712,7 @@ exec_context::evaluate (tree expr) const offset += additional_off.to_uhwi (); } - return storage_value.get_at (offset * CHAR_BIT, bit_width); + return storage_value.get_at (offset * CHAR_BIT + ptr_offset, bit_width); } break; @@ -5269,6 +5280,58 @@ data_value_print_tests () } +void +data_storage_set_at_tests () +{ + heap_memory mem; + context_printer printer; + + tree a5i = build_array_type_nelts (integer_type_node, 5); + tree v5i = create_var (a5i, "v5i"); + tree p = create_var (ptr_type_node, "p"); + + vec<tree> decls{}; + decls.safe_push (p); + decls.safe_push (v5i); + vec<tree> empty{}; + + context_builder builder {}; + builder.add_decls (&decls); + exec_context ctx = builder.build (mem, printer); + + data_storage *storage_p = ctx.find_reachable_var (p); + gcc_assert (storage_p != nullptr); + data_storage *storage_v5 = ctx.find_reachable_var (v5i); + gcc_assert (storage_v5 != nullptr); + + ASSERT_EQ (storage_p->get_value ().classify (), VAL_UNDEFINED); + + storage_address addr0 (storage_v5->get_ref (), 0); + data_value val0 (ptr_type_node); + val0.set_address (addr0); + + storage_p->set (val0); + + data_value valp0 = storage_p->get_value (); + ASSERT_EQ (valp0.classify (), VAL_ADDRESS); + storage_address *addrp0 = valp0.get_address (); + ASSERT_EQ (&addrp0->storage.get (), storage_v5); + ASSERT_EQ (addrp0->offset, 0); + + storage_address addr3 (storage_v5->get_ref (), 24); + data_value val3 (ptr_type_node); + val3.set_address (addr3); + + storage_p->set (val3); + + data_value valp3 = storage_p->get_value (); + ASSERT_EQ (valp3.classify (), VAL_ADDRESS); + storage_address *addrp3 = valp3.get_address (); + ASSERT_EQ (&addrp3->storage.get (), storage_v5); + ASSERT_EQ (addrp3->offset, 24); +} + + void context_printer_print_first_data_ref_part_tests () { @@ -5644,6 +5707,7 @@ context_printer_print_value_update_tests () const char *str = pp_formatted_text (&pp); ASSERT_STREQ (str, "# my_lhs = &my_var\n"); + context_printer printer2; pretty_printer & pp2 = printer2.pp; pp_buffer (&pp2)->m_flush_p = false; @@ -5748,6 +5812,33 @@ context_printer_print_value_update_tests () const char *str4 = pp_formatted_text (&pp4); ASSERT_STREQ (str4, "# v2i.der2i_i1 = 2\n# v2i.der2i_i2 = 11\n"); + + + heap_memory mem5; + context_printer printer5; + pretty_printer & pp5 = printer5.pp; + pp_buffer (&pp5)->m_flush_p = false; + + tree a5i = build_array_type_nelts (integer_type_node, 5); + tree v5i = create_var (a5i, "v5i"); + tree p = create_var (ptr_type_node, "p"); + + vec<tree> decls5{}; + decls5.safe_push (v5i); + decls5.safe_push (p); + + context_builder builder5; + builder5.add_decls (&decls5); + exec_context ctx5 = builder5.build (mem5, printer5); + + data_storage *strg_v5i = ctx5.find_reachable_var (v5i); + storage_address addr_v5i (strg_v5i->get_ref (), 24); + data_value val5 (ptr_type_node);; + val5.set_address (addr_v5i); + + printer5.print_value_update (ctx5, p, val5); + const char *str5 = pp_formatted_text (&pp5); + ASSERT_STREQ (str5, "# p = &v5i + 3B\n"); } @@ -6124,6 +6215,78 @@ exec_context_evaluate_tests () wide_int wi29_27 = val29_27.get_cst (); ASSERT_PRED1 (wi::fits_uhwi_p, wi29_27); ASSERT_EQ (wi29_27.to_uhwi (), 14); + + + tree a9i = build_array_type_nelts (integer_type_node, 9); + tree v9i = create_var (a9i, "v9i"); + tree p = create_var (ptr_type_node, "p"); + + vec<tree> decls9; + decls9.safe_push (v9i); + decls9.safe_push (p); + + context_builder builder9; + builder9.add_decls (&decls9); + exec_context ctx9 = builder9.build (mem, printer); + + data_storage * strg9 = ctx9.find_reachable_var (v9i); + gcc_assert (strg9 != nullptr); + wide_int cst10 = wi::shwi (10, HOST_BITS_PER_INT); + data_value val10 (integer_type_node); + val10.set_cst (cst10); + strg9->set_at (val10, HOST_BITS_PER_INT); + + data_storage * strg_p = ctx9.find_reachable_var (p); + gcc_assert (strg_p != nullptr); + storage_address addr_a9 (strg9->get_ref (), 0); + data_value val_addr9 (ptr_type_node); + val_addr9.set_address (addr_a9); + strg_p->set (val_addr9); + + tree ref1 = build2 (MEM_REF, integer_type_node, + p, build_int_cst (ptr_type_node, sizeof (int))); + + data_value val1 = ctx9.evaluate (ref1); + + ASSERT_EQ (val1.classify (), VAL_CONSTANT); + wide_int wi1 = val1.get_cst (); + ASSERT_PRED1 (wi::fits_uhwi_p, wi1); + ASSERT_EQ (wi1.to_uhwi (), 10); + + storage_address addr_a9p3 (strg9->get_ref (), 3 * HOST_BITS_PER_INT); + data_value val_addr9p3 (ptr_type_node); + val_addr9p3.set_address (addr_a9p3); + strg_p->set (val_addr9p3); + + wide_int cst16 = wi::shwi (16, HOST_BITS_PER_INT); + data_value val16 (integer_type_node); + val16.set_cst (cst16); + strg9->set_at (val16, 3 * HOST_BITS_PER_INT); + + tree ref3_bis = build2 (MEM_REF, integer_type_node, + p, build_zero_cst (ptr_type_node)); + + data_value val3 = ctx9.evaluate (ref3_bis); + + ASSERT_EQ (val3.classify (), VAL_CONSTANT); + wide_int wi3 = val3.get_cst (); + ASSERT_PRED1 (wi::fits_uhwi_p, wi3); + ASSERT_EQ (wi3.to_uhwi (), 16); + + wide_int cst19 = wi::shwi (19, HOST_BITS_PER_INT); + data_value val19 (integer_type_node); + val19.set_cst (cst19); + strg9->set_at (val19, 5 * HOST_BITS_PER_INT); + + tree ref5 = build2 (MEM_REF, integer_type_node, + p, build_int_cst (ptr_type_node, 2 * sizeof (int))); + + data_value val5 = ctx9.evaluate (ref5); + + ASSERT_EQ (val5.classify (), VAL_CONSTANT); + wide_int wi5 = val5.get_cst (); + ASSERT_PRED1 (wi::fits_uhwi_p, wi5); + ASSERT_EQ (wi5.to_uhwi (), 19); } @@ -7084,6 +7247,7 @@ gimple_exec_cc_tests () data_value_set_tests (); data_value_set_at_tests (); data_value_print_tests (); + data_storage_set_at_tests (); context_printer_print_first_data_ref_part_tests (); context_printer_print_value_update_tests (); exec_context_evaluate_tests ();