https://gcc.gnu.org/g:127052d9162868c5e3e787d80859fc5ed3d36ec6

commit 127052d9162868c5e3e787d80859fc5ed3d36ec6
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Sat Aug 30 22:22:39 2025 +0200

    gimple-simulate: Prise en charge tableaux non bornés

Diff:
---
 gcc/gimple-simulate.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 84 insertions(+), 6 deletions(-)

diff --git a/gcc/gimple-simulate.cc b/gcc/gimple-simulate.cc
index e33f8d8d5b46..7075c6e14cf7 100644
--- a/gcc/gimple-simulate.cc
+++ b/gcc/gimple-simulate.cc
@@ -806,17 +806,30 @@ context_printer::print_bb_entry (basic_block bb)
 
 static tree
 pick_subref_at (tree var_ref, unsigned min_offset,
-               int * ignored_bits, unsigned min_size)
+               int * ignored_bits, unsigned min_size,
+               tree target_type = NULL_TREE)
 {
   if (ignored_bits != nullptr)
     *ignored_bits = 0;
+  if (target_type != NULL_TREE
+      && TYPE_SIZE (target_type) != NULL_TREE)
+    min_size = get_constant_type_size (target_type);
   tree ref = var_ref;
   unsigned remaining_offset = min_offset;
   while (true)
     {
       tree var_type = TREE_TYPE (ref);
-      unsigned type_size = get_constant_type_size (var_type);
-      if (type_size == min_size)
+      if (target_type == NULL_TREE
+         || TYPE_SIZE (target_type) != NULL_TREE)
+       {
+         unsigned type_size = get_constant_type_size (var_type);
+         if (type_size == min_size)
+           break;
+       }
+      else if (var_type == target_type
+              || (TREE_CODE (var_type) == ARRAY_TYPE
+                  && TREE_CODE (target_type) == ARRAY_TYPE
+                  && TREE_TYPE (var_type) == TREE_TYPE (target_type)))
        break;
 
       if (TREE_CODE (var_type) == ARRAY_TYPE)
@@ -868,8 +881,13 @@ pick_subref_at (tree var_ref, unsigned min_offset,
 
          tree field_type = TREE_TYPE (field);
 
-         unsigned field_width = get_constant_type_size (field_type);
-         gcc_assert (field_width >= min_size);
+         if (TYPE_SIZE (field_type) == NULL_TREE)
+           gcc_assert (next_field == NULL_TREE);
+         else
+           {
+             unsigned field_width = get_constant_type_size (field_type);
+             gcc_assert (field_width >= min_size);
+           }
 
          ref = build3 (COMPONENT_REF, field_type,
                        ref, field, NULL_TREE);
@@ -960,7 +978,7 @@ find_mem_ref_replacement (tree * repl, unsigned * offset, 
simul_scope & context,
                  && wi::fits_uhwi_p (ref_offset));
 
       tree t = pick_subref_at (var_ref, ref_offset.to_uhwi (), nullptr,
-                              get_constant_type_size (access_type));
+                              0, access_type);
       if (t == NULL_TREE)
        {
          *repl = var_ref;
@@ -4534,6 +4552,66 @@ context_printer_print_first_data_ref_part_tests ()
   ASSERT_EQ (res15, integer_type_node);
   const char * str15 = pp_formatted_text (&pp15);
   ASSERT_STREQ (str15, "# d.der1a1i_a1[1]");
+
+
+  tree range = build_range_type (integer_type_node,
+                                build_zero_cst (integer_type_node),
+                                NULL_TREE);
+  tree ai = build_array_type (integer_type_node, range, false);
+
+  tree der1i1a = make_node (RECORD_TYPE);
+  tree der1i1a_a2 = build_decl (input_location, FIELD_DECL,
+                               get_identifier ("der1i1a_a2"), ai);
+  DECL_CONTEXT (der1i1a_a2) = der1i1a;
+  DECL_CHAIN (der1i1a_a2) = NULL_TREE;
+  tree der1i1a_i1 = build_decl (input_location, FIELD_DECL,
+                               get_identifier ("der1i1a_i1"),
+                               integer_type_node);
+  DECL_CONTEXT (der1i1a_i1) = der1i1a;
+  DECL_CHAIN (der1i1a_i1) = der1i1a_a2;
+  TYPE_FIELDS (der1i1a) = der1i1a_i1;
+  layout_type (der1i1a);
+
+  heap_memory mem16;
+
+  context_printer printer16;
+  pretty_printer & pp16 = printer16.pp;
+
+  tree d_16 = create_var (der1i1a, "d");
+  tree p_16 = create_var (ptr_type_node, "p");
+
+  vec<tree> decls16{};
+  decls16.safe_push (d_16);
+  decls16.safe_push (p_16);
+
+  context_builder builder16 {};
+  builder16.add_decls (&decls16);
+  simul_scope ctx16 = builder16.build (mem16, printer16);
+
+  data_storage *strg_d16 = ctx16.find_reachable_var (d_16);
+  gcc_assert (strg_d16 != nullptr);
+
+  storage_address addr_d16 (strg_d16->get_ref (), 0);
+  data_value val_p16 (ptr_type_node);
+  val_p16.set_address (addr_d16);
+
+  data_storage *strg_p16 = ctx16.find_reachable_var (p_16);
+  gcc_assert (strg_p16 != nullptr);
+  strg_p16->set (val_p16);
+
+  tree four_16 = build_int_cst (build_pointer_type (void_type_node),
+                               HOST_BITS_PER_INT / CHAR_BIT);
+  tree ref_d16 = build2 (MEM_REF, ai, p_16, four_16);
+  tree ref16 = build4 (ARRAY_REF, integer_type_node, ref_d16,
+                      build_one_cst (integer_type_node), NULL_TREE, NULL_TREE);
+
+  tree res16 = printer16.print_first_data_ref_part (ctx16, ref16, 0,
+                                                   nullptr,
+                                                   VAL_UNDEFINED);
+
+  ASSERT_EQ (res16, integer_type_node);
+  const char * str16 = pp_formatted_text (&pp16);
+  ASSERT_STREQ (str16, "# d.der1i1a_a2[1]");
 }

Reply via email to