[gcc(refs/users/mikael/heads/refactor_descriptor_v05)] Correction régression gomp/pr94672
Mikael Morin
mikael@gcc.gnu.org
Fri Jun 13 15:08:41 GMT 2025
https://gcc.gnu.org/g:7a2dc392bdca2ee323e484ef9dc47a7cc061e167
commit 7a2dc392bdca2ee323e484ef9dc47a7cc061e167
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Sat May 24 23:19:56 2025 +0200
Correction régression gomp/pr94672
Diff:
---
gcc/fortran/trans-array.cc | 16 ++++++----
gcc/fortran/trans-decl.cc | 48 +++++++++++++++++++++++++++---
gcc/fortran/trans-descriptor.cc | 3 +-
gcc/fortran/trans-expr.cc | 8 +++--
gcc/fortran/trans-intrinsic.cc | 3 +-
gcc/fortran/trans-stmt.cc | 3 +-
gcc/fortran/trans-types.cc | 65 +++++++++++++++++++++++++++++------------
gcc/fortran/trans-types.h | 4 +--
gcc/stor-layout.cc | 10 +++++--
9 files changed, 122 insertions(+), 38 deletions(-)
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 43e5e1e756bc..264abd407b46 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -1058,7 +1058,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss,
}
type =
gfc_get_array_type_bounds (eltype, total_dim, 0, from, to, 1,
- GFC_ARRAY_UNKNOWN, true);
+ GFC_ARRAY_UNKNOWN, true,
+ ss->info->expr ? ss->info->expr->ts.type
+ : BT_UNKNOWN);
/* Restore the upper bound, for the rest (not type-related) of the descriptor
initialization. */
if (to0)
@@ -2169,7 +2171,8 @@ gfc_build_constant_array_constructor (gfc_expr * expr, tree type)
NULL, tmp - 1);
}
- tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
+ tmptype = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true,
+ expr->ts.type);
/* as is not needed anymore. */
for (i = 0; i < as.rank + as.corank; i++)
@@ -7782,7 +7785,8 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, codim,
loop.from, loop.to, 0,
- GFC_ARRAY_UNKNOWN, false);
+ GFC_ARRAY_UNKNOWN, false,
+ expr->ts.type);
parm = gfc_create_var (parmtype, "parm");
/* When expression is a class object, then add the class' handle to
@@ -9157,7 +9161,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
{
cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
&ubound, 1,
- GFC_ARRAY_ALLOCATABLE, false);
+ GFC_ARRAY_ALLOCATABLE, false,
+ c->ts.type);
cdesc = gfc_create_var (cdesc, "cdesc");
DECL_ARTIFICIAL (cdesc) = 1;
@@ -9310,7 +9315,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest,
cdesc = gfc_get_array_type_bounds (tmp, 1, 0, &gfc_index_one_node,
&ubound, 1,
- GFC_ARRAY_ALLOCATABLE, false);
+ GFC_ARRAY_ALLOCATABLE, false,
+ c->ts.type);
cdesc = gfc_create_var (cdesc, "cdesc");
DECL_ARTIFICIAL (cdesc) = 1;
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 8e1dcbb8c1ec..32c0a8da6bee 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -1260,7 +1260,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
if (! COMPLETE_TYPE_P (type)
&& GFC_TYPE_ARRAY_SIZE (type)
- && GFC_TYPE_PACKED_ARRAY (type))
+ && GFC_TYPE_ARRAY_ELEM_LEN (type))
{
tree size, range;
@@ -1274,7 +1274,47 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
size, lower);
range = build_range_type (gfc_array_index_type, lower, size);
TYPE_DOMAIN (type) = range;
- layout_type (type);
+ if (GFC_TYPE_PACKED_ARRAY (type))
+ layout_type (type);
+ else
+ {
+ tree off = gfc_index_zero_node;
+ for (dim = 0; dim < GFC_TYPE_ARRAY_RANK (type); dim++)
+ {
+ tree lb = GFC_TYPE_ARRAY_LBOUND (type, dim);
+ tree ub = GFC_TYPE_ARRAY_UBOUND (type, dim);
+ tree extent = gfc_conv_array_extent_dim (lb, ub, nullptr);
+ tree extent_m1 = fold_build2_loc (input_location, MINUS_EXPR,
+ gfc_array_index_type, extent,
+ gfc_index_one_node);
+ tree spacing = GFC_TYPE_ARRAY_SPACING (type, dim);
+ tree tmp = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type,
+ extent_m1, spacing);
+ tmp = fold_build2_loc (input_location, MAX_EXPR,
+ gfc_array_index_type, tmp,
+ gfc_index_zero_node);
+ off = fold_build2_loc (input_location, PLUS_EXPR,
+ gfc_array_index_type, off, tmp);
+ }
+ tree elem_len = GFC_TYPE_ARRAY_ELEM_LEN (type);
+ elem_len = fold_convert_loc (input_location, gfc_array_index_type,
+ elem_len);
+ off = fold_build2_loc (input_location, PLUS_EXPR,
+ gfc_array_index_type, off, elem_len);
+ tree size_units = fold_build2_loc (input_location, EXACT_DIV_EXPR,
+ gfc_array_index_type,
+ off, elem_len);
+ tree size = fold_build2_loc (input_location, MULT_EXPR,
+ gfc_array_index_type, size_units,
+ build_int_cst (gfc_array_index_type,
+ BITS_PER_UNIT));
+ size_units = fold_convert_loc (input_location, sizetype, size_units);
+ TYPE_SIZE_UNIT (type) = size_units;
+ size = fold_convert_loc (input_location, sizetype, size);
+ TYPE_SIZE (type) = size;
+ layout_type (type);
+ }
}
}
@@ -1373,8 +1413,8 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
gfc_typenode_for_spec () returns the array descriptor. */
type = is_classarray ? gfc_get_element_type (type)
: gfc_typenode_for_spec (&sym->ts);
- type = gfc_get_nodesc_array_type (type, as, packed,
- !sym->attr.target);
+ type = gfc_get_nodesc_array_type (type, as, packed, !sym->attr.target,
+ sym->ts.type);
}
else
{
diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc
index 1bded77e00a9..e41809f0037a 100644
--- a/gcc/fortran/trans-descriptor.cc
+++ b/gcc/fortran/trans-descriptor.cc
@@ -2590,7 +2590,8 @@ gfc_get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
if (POINTER_TYPE_P (TREE_TYPE (scalar)))
scalar = TREE_TYPE (scalar);
return gfc_get_array_type_bounds (TREE_TYPE (scalar), 0, 0, NULL, NULL, 1,
- akind, !(attr.pointer || attr.target));
+ akind, !(attr.pointer || attr.target),
+ BT_UNKNOWN);
}
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 8b32de1ef292..154b1bc862b7 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -132,7 +132,8 @@ gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol *sym, gfc_expr *expr)
tree elt_type = gfc_typenode_for_spec (&sym->ts);
tree desc_type = gfc_get_array_type_bounds (elt_type, expr->rank, 0,
lower, upper, 0,
- GFC_ARRAY_UNKNOWN, false);
+ GFC_ARRAY_UNKNOWN, false,
+ expr->ts.type);
tree desc = gfc_create_var (desc_type, "desc");
DECL_ARTIFICIAL (desc) = 1;
@@ -4811,7 +4812,7 @@ gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
type = gfc_typenode_for_spec (&sym->ts);
type = gfc_get_nodesc_array_type (type, sym->as, packed,
!sym->attr.target && !sym->attr.pointer
- && !sym->attr.proc_pointer);
+ && !sym->attr.proc_pointer, sym->ts.type);
var = gfc_create_var (type, "ifm");
gfc_add_modify (block, var, fold_convert (type, data));
@@ -10891,7 +10892,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
tmp = gfc_typenode_for_spec (&expr2->ts);
tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
bound, bound, 0,
- GFC_ARRAY_POINTER_CONT, false);
+ GFC_ARRAY_POINTER_CONT, false,
+ expr2->ts.type);
tmp = gfc_create_var (tmp, "ptrtemp");
rse.descriptor_only = 0;
rse.expr = tmp;
diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index f264e79732e5..4a7a3cd77a1a 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -4997,7 +4997,8 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
&arrayexpr->where,
arrayexpr->rank - 1);
- tree array = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true);
+ tree array = gfc_get_nodesc_array_type (type, &as, PACKED_STATIC, true,
+ BT_INTEGER);
result_var = gfc_create_var (array, "loc_result");
}
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index f11437430ed5..afc6605c6d8f 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -5052,7 +5052,8 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
parmtype = gfc_get_element_type (TREE_TYPE (desc));
parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
loop.from, loop.to, 1,
- GFC_ARRAY_UNKNOWN, true);
+ GFC_ARRAY_UNKNOWN, true,
+ expr2->ts.type);
/* Allocate temporary for nested forall construct. */
tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 50175dea2c7e..d86396065e36 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -1589,7 +1589,7 @@ gfc_is_nodesc_array (gfc_symbol * sym)
static tree
gfc_build_array_type (tree type, gfc_array_spec * as,
enum gfc_array_kind akind, bool restricted,
- bool contiguous, int codim)
+ bool contiguous, int codim, bt type_type)
{
tree lbound[GFC_MAX_DIMENSIONS];
tree ubound[GFC_MAX_DIMENSIONS];
@@ -1647,7 +1647,7 @@ gfc_build_array_type (tree type, gfc_array_spec * as,
return gfc_get_array_type_bounds (type, as->rank == -1
? GFC_MAX_DIMENSIONS : as->rank,
corank, lbound, ubound, 0, akind,
- restricted);
+ restricted, type_type);
}
/* Returns the struct descriptor_dimension type. */
@@ -1851,7 +1851,7 @@ gfc_get_dtype (tree type, int * rank)
tree
gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
- bool restricted)
+ bool restricted, bt type_type)
{
tree lbound[GFC_MAX_DIMENSIONS];
tree ubound[GFC_MAX_DIMENSIONS];
@@ -2034,7 +2034,11 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
layout_type (type);
- if (packed != PACKED_NO)
+ if (type_type != BT_UNKNOWN
+ && type_type != BT_CLASS
+ && (type_type != BT_CHARACTER
+ || (TREE_CODE (etype) == ARRAY_TYPE
+ && TYPE_SIZE_UNIT (etype))))
GFC_TYPE_ARRAY_ELEM_LEN (type) = TYPE_SIZE_UNIT (etype);
if (packed == PACKED_FULL || packed == PACKED_STATIC)
@@ -2168,7 +2172,8 @@ gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted)
tree
gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
tree * ubound, int packed,
- enum gfc_array_kind akind, bool restricted)
+ enum gfc_array_kind akind, bool restricted,
+ bt type_type)
{
char name[8 + 2*GFC_RANK_DIGITS + 1 + GFC_MAX_SYMBOL_LEN];
tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype;
@@ -2219,21 +2224,29 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
GFC_TYPE_ARRAY_DTYPE (fat_type) = NULL_TREE;
GFC_TYPE_ARRAY_AKIND (fat_type) = akind;
+ if (type_type != BT_UNKNOWN
+ && type_type != BT_CLASS
+ && (type_type != BT_CHARACTER
+ || (TREE_CODE (etype) == ARRAY_TYPE
+ && TYPE_SIZE_UNIT (etype) != NULL_TREE)))
+ GFC_TYPE_ARRAY_ELEM_LEN (fat_type) = TYPE_SIZE_UNIT (etype);
+
/* Build an array descriptor record type. */
tree spacing;
- if (packed == 0)
- {
- stride = NULL_TREE;
- spacing = NULL_TREE;
- }
- else
+ if (packed != PACKED_NO
+ && GFC_TYPE_ARRAY_ELEM_LEN (fat_type))
{
stride = gfc_index_one_node;
if (dimen == 0)
spacing = NULL_TREE;
else
spacing = fold_convert_loc (input_location, gfc_array_index_type,
- TYPE_SIZE_UNIT (etype));
+ GFC_TYPE_ARRAY_ELEM_LEN (fat_type));
+ }
+ else
+ {
+ stride = NULL_TREE;
+ spacing = NULL_TREE;
}
for (n = 0; n < dimen + codimen; n++)
{
@@ -2304,10 +2317,21 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
return fat_type;
}
+ bool contiguous = packed == PACKED_FULL
+ || packed == PACKED_STATIC
+ || akind == GFC_ARRAY_ASSUMED_SHAPE_CONT
+ || akind == GFC_ARRAY_ASSUMED_RANK_CONT
+ || akind == GFC_ARRAY_ASSUMED_RANK_ALLOCATABLE
+ || akind == GFC_ARRAY_ASSUMED_RANK_POINTER_CONT
+ || akind == GFC_ARRAY_ALLOCATABLE
+ || akind == GFC_ARRAY_POINTER_CONT;
+ if (contiguous)
+ GFC_TYPE_PACKED_ARRAY (fat_type) = 1;
+
/* We define data as an array with the correct size if possible.
Much better than doing pointer arithmetic. */
bool known_zero_size = false;
- if (stride)
+ if (stride && contiguous)
{
tree range_bound = int_const_binop (MINUS_EXPR, stride,
build_int_cst (TREE_TYPE (stride),
@@ -2318,7 +2342,8 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
known_zero_size = true;
}
else
- rtype = gfc_array_range_type;
+ rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node,
+ NULL_TREE);
if (known_zero_size
&& TREE_CODE (etype) == ARRAY_TYPE
&& TYPE_DOMAIN (etype)
@@ -2613,7 +2638,8 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
type = gfc_get_nodesc_array_type (type, sym->as,
byref ? PACKED_FULL
: PACKED_STATIC,
- restricted);
+ restricted,
+ sym->ts.type);
byref = 0;
}
}
@@ -2626,7 +2652,8 @@ gfc_sym_type (gfc_symbol * sym, bool is_bind_c)
else if (sym->attr.allocatable)
akind = GFC_ARRAY_ALLOCATABLE;
type = gfc_build_array_type (type, sym->as, akind, restricted,
- sym->attr.contiguous, sym->as->corank);
+ sym->attr.contiguous, sym->as->corank,
+ sym->ts.type);
}
}
else
@@ -3264,13 +3291,15 @@ gfc_get_derived_type (gfc_symbol * derived, int codimen)
(
field_type, c->as, akind, !c->attr.target && !c->attr.pointer,
c->attr.contiguous,
- c->attr.codimension || c->attr.pointer ? codimen : 0
+ c->attr.codimension || c->attr.pointer ? codimen : 0,
+ c->ts.type
);
}
else
field_type = gfc_get_nodesc_array_type (field_type, c->as,
PACKED_STATIC,
- !c->attr.target);
+ !c->attr.target,
+ c->ts.type);
}
else if ((c->attr.pointer || c->attr.allocatable || c->attr.pdt_string)
&& !c->attr.proc_pointer
diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h
index 6c981ad2f3d7..5ead5f7aadb9 100644
--- a/gcc/fortran/trans-types.h
+++ b/gcc/fortran/trans-types.h
@@ -100,8 +100,8 @@ tree gfc_build_uint_type (int);
tree gfc_get_element_type (tree);
tree gfc_get_array_type_bounds (tree, int, int, tree *, tree *, int,
- enum gfc_array_kind, bool);
-tree gfc_get_nodesc_array_type (tree, gfc_array_spec *, gfc_packed, bool);
+ enum gfc_array_kind, bool, bt);
+tree gfc_get_nodesc_array_type (tree, gfc_array_spec *, gfc_packed, bool, bt);
/* Add a field of given name and type to a UNION_TYPE or RECORD_TYPE. */
tree gfc_add_field_to_struct (tree, tree, tree, tree **);
diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc
index 12071c96ca79..7095ab7e1fde 100644
--- a/gcc/stor-layout.cc
+++ b/gcc/stor-layout.cc
@@ -2446,7 +2446,7 @@ layout_type (tree type)
type = TYPE_MAIN_VARIANT (type);
/* Do nothing if type has been laid out before. */
- if (TYPE_SIZE (type))
+ if (TYPE_SIZE (type) && TYPE_ALIGN (type))
return;
switch (TREE_CODE (type))
@@ -2665,8 +2665,12 @@ layout_type (tree type)
tree element = TREE_TYPE (type);
/* We need to know both bounds in order to compute the size. */
- if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
- && TYPE_SIZE (element))
+ if (index
+ && TYPE_MAX_VALUE (index)
+ && TYPE_MIN_VALUE (index)
+ && TYPE_SIZE (element)
+ && !TYPE_SIZE (type)
+ && !TYPE_SIZE_UNIT (type))
{
tree ub = TYPE_MAX_VALUE (index);
tree lb = TYPE_MIN_VALUE (index);
More information about the Gcc-cvs
mailing list