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

commit b68e4d2ef22d8fe82d628a320c6577d1d0a946dd
Author: Mikael Morin <mik...@gcc.gnu.org>
Date:   Wed Dec 18 19:04:41 2024 +0100

    Utilisation de la méthode de nullification pour nullifier un pointeur
    
    Correction régression modifiable_p
    
    Correction dump
    
    Ajout assertion
    
    Correction assertion même type

Diff:
---
 gcc/fortran/trans-array.cc                      | 96 ++++++++++++++++++-------
 gcc/fortran/trans-array.h                       |  1 +
 gcc/fortran/trans-expr.cc                       | 35 ++++++++-
 gcc/testsuite/gfortran.dg/class_allocate_14.f90 |  2 +-
 4 files changed, 106 insertions(+), 28 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index cdbff27d82ca..4c237b561aa6 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -545,9 +545,9 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree 
desc,
 
 
 static int
-get_type_info (const gfc_typespec &ts)
+get_type_info (const bt &type)
 {
-  switch (ts.type)
+  switch (type)
     {
     case BT_INTEGER:
     case BT_LOGICAL:
@@ -558,7 +558,7 @@ get_type_info (const gfc_typespec &ts)
     case BT_CLASS:
     case BT_VOID:
     case BT_UNSIGNED:
-      return ts.type;
+      return type;
 
     case BT_PROCEDURE:
     case BT_ASSUMED:
@@ -613,11 +613,34 @@ get_size_info (gfc_typespec &ts)
 }
 
 
-class init_info
+class modify_info
 {
 public:
+  virtual bool is_initialization () const { return false; }
   virtual bool initialize_data () const { return false; }
   virtual tree get_data_value () const { return NULL_TREE; }
+};
+
+class nullification : public modify_info
+{
+  virtual bool initialize_data () const { return true; }
+  virtual tree get_data_value () const { return null_pointer_node; }
+  /*
+private:
+  gfc_typespec &ts;
+
+public:
+  null_init(gfc_typespec &arg_ts) : ts(arg_ts) { }
+  virtual bool initialize_data () const { return true; }
+  virtual tree get_data_value () const { return null_pointer_node; }
+  virtual gfc_typespec *get_type () const { return &ts; }
+  */
+};
+
+class init_info : public modify_info
+{
+public:
+  virtual bool is_initialization () const { return true; }
   virtual gfc_typespec *get_type () const { return nullptr; }
 };
 
@@ -638,13 +661,13 @@ public:
   }
 };
 
-class nullification : public init_info
+class null_init : public init_info
 {
 private:
   gfc_typespec &ts;
 
 public:
-  nullification(gfc_typespec &arg_ts) : ts(arg_ts) { }
+  null_init(gfc_typespec &arg_ts) : ts(arg_ts) { }
   virtual bool initialize_data () const { return true; }
   virtual tree get_data_value () const { return null_pointer_node; }
   virtual gfc_typespec *get_type () const { return &ts; }
@@ -700,13 +723,12 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &,
       CONSTRUCTOR_APPEND_ELT (v, rank_field, rank_val);
     }
 
-  if (type_info->type != BT_CLASS)
-    {
-      tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
-      tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
-                                         get_type_info (*type_info));
-      CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val);
-    }
+  tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
+  tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
+                                     get_type_info (type_info->type == BT_CLASS
+                                                    ? BT_DERIVED
+                                                    : type_info->type));
+  CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val);
 
   return build_constructor (type, v);
 }
@@ -715,8 +737,8 @@ build_dtype (gfc_typespec &ts, int rank, const 
symbol_attribute &,
 /* Build a null array descriptor constructor.  */
 
 vec<constructor_elt, va_gc> *
-get_descriptor_init (tree type, gfc_typespec &ts, int rank,
-                    const symbol_attribute &attr, const init_info &init)
+get_descriptor_init (tree type, gfc_typespec *ts, int rank,
+                    const symbol_attribute *attr, const modify_info &init)
 {
   vec<constructor_elt, va_gc> *v = nullptr;
 
@@ -732,11 +754,15 @@ get_descriptor_init (tree type, gfc_typespec &ts, int 
rank,
       CONSTRUCTOR_APPEND_ELT (v, data_field, data_value);
     }
 
-  tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD);
-  tree dtype_value = build_dtype (ts, rank, attr, init);
-  CONSTRUCTOR_APPEND_ELT (v, dtype_field, dtype_value);
+  if (init.is_initialization ())
+    {
+      tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD);
+      tree dtype_value = build_dtype (*ts, rank, *attr,
+                                     static_cast<const init_info &> (init));
+      CONSTRUCTOR_APPEND_ELT (v, dtype_field, dtype_value);
+    }
 
-  if (flag_coarray == GFC_FCOARRAY_LIB && attr.codimension)
+  if (flag_coarray == GFC_FCOARRAY_LIB && attr->codimension)
     {
       /* Declare the variable static so its array descriptor stays present
         after leaving the scope.  It may still be accessed through another
@@ -759,7 +785,7 @@ get_default_array_descriptor_init (tree type, gfc_typespec 
&ts, int rank,
   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
   gcc_assert (DATA_FIELD == 0);
 
-  return get_descriptor_init (type, ts, rank, attr, default_init (attr));
+  return get_descriptor_init (type, &ts, rank, &attr, default_init (attr));
 }
 
 
@@ -767,7 +793,14 @@ vec<constructor_elt, va_gc> *
 get_null_array_descriptor_init (tree type, gfc_typespec &ts, int rank,
                                const symbol_attribute &attr)
 {
-  return get_descriptor_init (type, ts, rank, attr, nullification (ts));
+  return get_descriptor_init (type, &ts, rank, &attr, null_init (ts));
+}
+
+
+vec<constructor_elt, va_gc> *
+get_null_array_descriptor (tree type, const symbol_attribute &attr)
+{
+  return get_descriptor_init (type, nullptr, 0, &attr, nullification ());
 }
 
 
@@ -778,7 +811,7 @@ gfc_build_default_array_descriptor (tree type, gfc_typespec 
&ts, int rank,
   gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
 
   return build_constructor (type,
-                           get_descriptor_init (type, ts, rank, attr,
+                           get_descriptor_init (type, &ts, rank, &attr,
                                                 default_init (attr)));
 }
 
@@ -901,6 +934,9 @@ modifiable_p (tree data_ref)
 {
   switch (TREE_CODE (data_ref))
     {
+    case INDIRECT_REF:
+      return true;
+
     case CONST_DECL:
       return false;
 
@@ -1056,6 +1092,18 @@ gfc_clear_descriptor (stmtblock_t *block, gfc_symbol 
*sym, tree descriptor)
 }
 
 
+void
+gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *expr, tree descriptor)
+{
+  symbol_attribute attr;
+
+  attr = gfc_expr_attr (expr);
+
+  init_struct (block, descriptor,
+              get_null_array_descriptor (TREE_TYPE (descriptor), attr));
+}
+
+
 void
 gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *sym, 
                      gfc_expr *expr, tree descriptor)
@@ -1088,8 +1136,8 @@ gfc_set_scalar_descriptor (stmtblock_t *block, tree 
descriptor,
   attr = gfc_symbol_attr (sym);
 
   init_struct (block, descriptor,
-              get_descriptor_init (TREE_TYPE (descriptor), sym->ts, 0,
-                                   attr, scalar_value (expr->ts, value)));
+              get_descriptor_init (TREE_TYPE (descriptor), &sym->ts, 0,
+                                   &attr, scalar_value (expr->ts, value)));
 }
 
 
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 3b05a2eb197a..8df55c2c00a5 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -142,6 +142,7 @@ void gfc_conv_resolve_dependencies (gfc_loopinfo *, gfc_ss 
*, gfc_ss *);
 tree gfc_build_null_descriptor (tree);
 tree gfc_build_default_class_descriptor (tree, gfc_typespec &);
 void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, tree);
+void gfc_nullify_descriptor (stmtblock_t *block, gfc_expr *, tree);
 void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, gfc_expr *, tree);
 void gfc_set_scalar_descriptor (stmtblock_t *block, tree, gfc_symbol *, 
gfc_expr *, tree);
 
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 1de4a73974d6..003754cdad6f 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -828,9 +828,27 @@ gfc_get_vptr_from_expr (tree expr)
   return NULL_TREE;
 }
 
+
+static int
+descriptor_rank (tree descriptor)
+{
+  tree dim = gfc_get_descriptor_dimension (descriptor);
+  tree dim_type = TREE_TYPE (dim);
+  gcc_assert (TREE_CODE (dim_type) == ARRAY_TYPE);
+  tree idx_type = TYPE_DOMAIN (dim_type);
+  gcc_assert (TREE_CODE (idx_type) == INTEGER_TYPE);
+  gcc_assert (integer_zerop (TYPE_MIN_VALUE (idx_type)));
+  tree idx_max = TYPE_MAX_VALUE (idx_type);
+  if (idx_max == NULL_TREE)
+    return GFC_MAX_DIMENSIONS;
+  wide_int max = wi::to_wide (idx_max);
+  return max.to_shwi () + 1;
+}
+
+
 void
 gfc_class_array_data_assign (stmtblock_t *block, tree lhs_desc, tree rhs_desc,
-                            bool lhs_type)
+                            bool)
 {
   tree tmp, tmp2, type;
 
@@ -846,7 +864,18 @@ gfc_class_array_data_assign (stmtblock_t *block, tree 
lhs_desc, tree rhs_desc,
   tmp = gfc_get_descriptor_dimension (lhs_desc);
   tmp2 = gfc_get_descriptor_dimension (rhs_desc);
 
-  type = lhs_type ? TREE_TYPE (tmp) : TREE_TYPE (tmp2);
+  int rank = descriptor_rank (lhs_desc);
+  int rank2 = descriptor_rank (rhs_desc);
+  if (rank == GFC_MAX_DIMENSIONS && rank2 != GFC_MAX_DIMENSIONS)
+    type = TREE_TYPE (tmp2);
+  else if (rank2 == GFC_MAX_DIMENSIONS && rank != GFC_MAX_DIMENSIONS)
+    type = TREE_TYPE (tmp);
+  else
+    {
+      gcc_assert (TREE_TYPE (tmp) == TREE_TYPE (tmp2));
+      type = TREE_TYPE (tmp);
+    }
+
   tmp = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp,
                    gfc_index_zero_node, NULL_TREE, NULL_TREE);
   tmp2 = build4_loc (input_location, ARRAY_RANGE_REF, type, tmp2,
@@ -10904,7 +10933,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, 
gfc_expr * expr2)
       if (expr2->expr_type == EXPR_NULL)
        {
          /* Just set the data pointer to null.  */
-         gfc_conv_descriptor_data_set (&lse.pre, lse.expr, null_pointer_node);
+         gfc_nullify_descriptor (&lse.pre, expr1, lse.expr);
        }
       else if (rank_remap)
        {
diff --git a/gcc/testsuite/gfortran.dg/class_allocate_14.f90 
b/gcc/testsuite/gfortran.dg/class_allocate_14.f90
index 01f02ab6e47a..d938d2536980 100644
--- a/gcc/testsuite/gfortran.dg/class_allocate_14.f90
+++ b/gcc/testsuite/gfortran.dg/class_allocate_14.f90
@@ -25,6 +25,6 @@ call sub()
 call sub2()
 end
 
-! { dg-final { scan-tree-dump-times "static struct __class_m_T_1_0a b = 
{._data={.data=0B, .dtype={.version=0, .rank=1}}, ._vptr=&__vtab_m_T};" 1 
"original" } }
+! { dg-final { scan-tree-dump-times "static struct __class_m_T_1_0a b = 
{._data={.data=0B, .dtype={.version=0, .rank=1, .type=5}}, 
._vptr=&__vtab_m_T};" 1 "original" } }
 ! { dg-final { scan-tree-dump-times "static struct __class_m_T_a y = 
{._data=0B, ._vptr=&__vtab_m_T};" 1 "original" } }

Reply via email to