[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