https://gcc.gnu.org/g:d8608d4bdeefce8e994be9b37cf94181dbb64580

commit d8608d4bdeefce8e994be9b37cf94181dbb64580
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Fri Aug 29 14:38:54 2025 +0200

    gimple-simulate: Correction ICE extraction ref avec padding

Diff:
---
 gcc/gimple-simulate.cc | 112 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 89 insertions(+), 23 deletions(-)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index aeda491db332..a887bba872cf 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -899,9 +899,9 @@ pick_subref_at (tree var_ref, unsigned offset, int * 
ignored_bits,
    size MIN_SIZE bits.  Return NULL_TREE if such a data reference was not 
found,
    otherwise return the reference found.  */
 
-static tree
-find_mem_ref_replacement (simul_scope & context, tree data_ref,
-                         unsigned offset, unsigned min_size)
+static bool
+find_mem_ref_replacement (tree * repl, unsigned * offset, simul_scope & 
context,
+                         tree data_ref)
 {
   gcc_assert (TREE_CODE (data_ref) == MEM_REF
              || TREE_CODE (data_ref) == TARGET_MEM_REF);
@@ -909,26 +909,30 @@ find_mem_ref_replacement (simul_scope & context, tree 
data_ref,
   tree ptr = TREE_OPERAND (data_ref, 0);
   data_value ptr_val = context.evaluate (ptr);
   if (ptr_val.classify () != VAL_ADDRESS)
-    return NULL_TREE;
+    return false;
 
   storage_address *ptr_address = ptr_val.get_address ();
   data_storage &ptr_target = ptr_address->storage.get ();
   if (ptr_target.get_type () != STRG_VARIABLE)
-    return NULL_TREE;
+    return false;
 
   tree access_type = TREE_TYPE (data_ref);
   tree var_ref = ptr_target.get_variable ();
   tree var_type = TREE_TYPE (var_ref);
 
   if (var_type == access_type)
-    return var_ref;
+    {
+      *repl = var_ref;
+      gcc_assert (*offset == 0 && ptr_address->offset == 0);
+      return true;
+    }
   else
     {
       tree access_offset = TREE_OPERAND (data_ref, 1);
       gcc_assert (TREE_CONSTANT (access_offset));
       wide_int wi_offset = wi::to_wide (access_offset);
       wide_int remaining_offset = wi_offset * CHAR_BIT
-                                 + offset + ptr_address->offset;
+                                 + *offset + ptr_address->offset;
 
       gcc_assert (wi::ges_p (remaining_offset, 0)
                  && wi::fits_shwi_p (remaining_offset));
@@ -948,8 +952,9 @@ find_mem_ref_replacement (simul_scope & context, tree 
data_ref,
          remaining_offset += wi_idx * CHAR_BIT;
        }
 
-      return pick_subref_at (var_ref, remaining_offset.to_shwi (), nullptr,
-                            min_size);
+      *repl = var_ref;
+      *offset = remaining_offset.to_shwi ();
+      return true;
     }
 }
 
@@ -974,16 +979,20 @@ context_printer::print_first_data_ref_part (simul_scope & 
context,
     min_size = CHAR_BIT;
 
   tree default_ref = NULL_TREE;
+  tree ref = NULL_TREE;
   switch (TREE_CODE (data_ref))
     {
     case MEM_REF:
     case TARGET_MEM_REF:
       {
-       tree mem_replacement = find_mem_ref_replacement (context, data_ref,
-                                                        offset, min_size);
-       if (mem_replacement != NULL_TREE)
-         return print_first_data_ref_part (context, mem_replacement, 0,
-                                           ignored_bits, val_type);
+       tree mem_replacement;
+       if (find_mem_ref_replacement (&mem_replacement, &offset, context,
+                                     data_ref))
+         {
+           ref = pick_subref_at (mem_replacement, offset, ignored_bits, 
min_size);
+           if (ref != NULL_TREE)
+             break;
+         }
 
        unsigned orig_type_size;
        orig_type_size = get_constant_type_size (TREE_TYPE (data_ref));
@@ -1008,7 +1017,7 @@ context_printer::print_first_data_ref_part (simul_scope & 
context,
     /* Fall through.  */
 
     default:
-      tree ref = pick_subref_at (data_ref, offset, ignored_bits, min_size);
+      ref = pick_subref_at (data_ref, offset, ignored_bits, min_size);
       if (ref == NULL_TREE)
        {
          if (ignored_bits != nullptr && *ignored_bits > 0)
@@ -1018,13 +1027,14 @@ context_printer::print_first_data_ref_part (simul_scope 
& context,
          if (ref == NULL_TREE)
            ref = data_ref;
        }
-
-      pp_indent (&pp);
-      pp_character (&pp, '#');
-      pp_space (&pp);
-      print (&context, ref);
-      return TREE_TYPE (ref);
+      break;
     }
+
+  pp_indent (&pp);
+  pp_character (&pp, '#');
+  pp_space (&pp);
+  print (&context, ref);
+  return TREE_TYPE (ref);
 }
 
 
@@ -3898,8 +3908,8 @@ context_printer_print_first_data_ref_part_tests ()
   simul_scope ctx3 = builder3.build (mem1, printer3);
 
   tree long_var2i = build2 (MEM_REF, long_integer_type_node,
-                          build1 (ADDR_EXPR, ptr_type_node, var2i),
-                          build_zero_cst (ptr_type_node));
+                           build1 (ADDR_EXPR, ptr_type_node, var2i),
+                           build_zero_cst (ptr_type_node));
 
   tree res3 = printer3.print_first_data_ref_part (ctx3, long_var2i, 0, nullptr,
                                                  VAL_UNDEFINED);
@@ -4225,6 +4235,62 @@ context_printer_print_first_data_ref_part_tests ()
   ASSERT_EQ (res12, integer_type_node);
   const char * str12 = pp_formatted_text (&pp12);
   ASSERT_STREQ (str12, "# i12[0]");
+
+
+  tree der1s1l = make_node (RECORD_TYPE);
+  tree der1s1l_l2 = build_decl (input_location, FIELD_DECL,
+                               get_identifier ("der1s1l_l2"),
+                               long_integer_type_node);
+  DECL_CONTEXT (der1s1l_l2) = der1s1l;
+  DECL_CHAIN (der1s1l_l2) = NULL_TREE;
+  tree der1s1l_s1 = build_decl (input_location, FIELD_DECL,
+                               get_identifier ("der1s1l_s1"),
+                               short_integer_type_node);
+  DECL_CONTEXT (der1s1l_s1) = der1s1l;
+  DECL_CHAIN (der1s1l_s1) = der1s1l_l2;
+  TYPE_FIELDS (der1s1l) = der1s1l_s1;
+  layout_type (der1s1l);
+
+  tree ad1s1l = build_array_type_nelts (der1s1l, 2);
+  tree var1s1l_13 = create_var (ad1s1l, "var1s1l");
+  tree pd1s1l = build_pointer_type (der1s1l);
+  tree p13 = create_var (pd1s1l, "p");
+
+  vec<tree> decls13{};
+  decls13.safe_push (var1s1l_13);
+  decls13.safe_push (p13);
+
+  heap_memory mem13;
+  context_printer printer13;
+  pretty_printer & pp13 = printer13.pp;
+
+  context_builder builder13 {};
+  builder13.add_decls (&decls13);
+  simul_scope ctx13 = builder13.build (mem13, printer13);
+
+  data_storage *strg_var13 = ctx13.find_reachable_var (var1s1l_13);
+  gcc_assert (strg_var13 != nullptr);
+
+  storage_address addr_var13 (strg_var13->get_ref (), 0);
+  data_value val_p13 (pd1s1l);
+  val_p13.set_address (addr_var13);
+
+  data_storage *strg_p13 = ctx13.find_reachable_var (p13);
+  gcc_assert (strg_p13 != nullptr);
+  strg_p13->set (val_p13);
+
+  tree ref_p13 = build2 (MEM_REF, der1s1l, p13, build_int_cst (pd1s1l, 0));
+
+  int ignored_bits;
+  tree res13 = printer13.print_first_data_ref_part (ctx13, ref_p13,
+                                                   HOST_BITS_PER_SHORT,
+                                                   &ignored_bits,
+                                                   VAL_UNDEFINED);
+
+  ASSERT_EQ (res13, long_integer_type_node);
+  const char * str13 = pp_formatted_text (&pp13);
+  ASSERT_STREQ (str13, "# var1s1l[0].der1s1l_l2");
+  ASSERT_EQ (ignored_bits, HOST_BITS_PER_LONG - HOST_BITS_PER_SHORT);
 }

Reply via email to