[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Utilisation de la méthode de nullification pour nullifier un pointeur
Mikael Morin
mikael@gcc.gnu.org
Fri Jun 13 14:40:23 GMT 2025
https://gcc.gnu.org/g:b265c07098591e529862604dd897afa7258d7e59
commit b265c07098591e529862604dd897afa7258d7e59
Author: Mikael Morin <mikael@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 8f0dff10fd81..0560c7482ee5 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -547,9 +547,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:
@@ -560,7 +560,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:
@@ -615,11 +615,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; }
};
@@ -640,13 +663,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; }
@@ -702,13 +725,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);
}
@@ -717,8 +739,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;
@@ -734,11 +756,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
@@ -761,7 +787,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));
}
@@ -769,7 +795,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 ());
}
@@ -780,7 +813,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)));
}
@@ -903,6 +936,9 @@ modifiable_p (tree data_ref)
{
switch (TREE_CODE (data_ref))
{
+ case INDIRECT_REF:
+ return true;
+
case CONST_DECL:
return false;
@@ -1058,6 +1094,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)
@@ -1090,8 +1138,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 3a166a728708..e6b5c397d651 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,
@@ -11123,7 +11152,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" } }
More information about the Gcc-cvs
mailing list