diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index f0138b0..e1c5137 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -783,7 +783,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) TREE_NO_WARNING (GFC_TYPE_ARRAY_UBOUND (type, dim)) = 1; } } - if (GFC_TYPE_ARRAY_OFFSET (type) == NULL_TREE) + if (GFC_TYPE_ARRAY_OFFSET (type) == NULL_TREE && GFC_TYPE_ARRAY_RANK (type)) { GFC_TYPE_ARRAY_OFFSET (type) = gfc_create_var_np (gfc_array_index_type, "offset"); @@ -795,7 +795,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) gfc_add_decl_to_function (GFC_TYPE_ARRAY_OFFSET (type)); } - if (GFC_TYPE_ARRAY_SIZE (type) == NULL_TREE + if (GFC_TYPE_ARRAY_SIZE (type) == NULL_TREE && GFC_TYPE_ARRAY_RANK (type) && sym->as->type != AS_ASSUMED_SIZE) { GFC_TYPE_ARRAY_SIZE (type) = create_index_var ("size", nest); @@ -810,7 +810,8 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) type = TREE_TYPE (type); } - if (! COMPLETE_TYPE_P (type) && GFC_TYPE_ARRAY_SIZE (type)) + if (GFC_TYPE_ARRAY_RANK (type) && ! COMPLETE_TYPE_P (type) + && GFC_TYPE_ARRAY_SIZE (type)) { tree size, range; @@ -822,7 +823,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) layout_type (type); } - if (TYPE_NAME (type) != NULL_TREE + if (TYPE_NAME (type) != NULL_TREE && sym->as->rank && GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1) != NULL_TREE && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1)) == VAR_DECL) { @@ -842,7 +843,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) { tree gtype = TREE_TYPE (type), rtype, type_decl; - for (dim = sym->as->rank - 1; dim >= 0; dim--) + for (dim = sym->as->rank + sym->as->corank - 1; dim >= 0; dim--) { tree lbound, ubound; lbound = GFC_TYPE_ARRAY_LBOUND (type, dim); @@ -914,7 +915,8 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy) { /* For descriptorless arrays with known element size the actual argument is sufficient. */ - gcc_assert (GFC_ARRAY_TYPE_P (type)); + gcc_assert (GFC_ARRAY_TYPE_P (type) + || GFC_ARRAY_TYPE_P (TREE_TYPE (type))); gfc_build_qualified_array (dummy, sym); return dummy; } @@ -1228,7 +1230,8 @@ gfc_get_symbol_decl (gfc_symbol * sym) } /* Use a copy of the descriptor for dummy arrays. */ - if (sym->attr.dimension && !TREE_USED (sym->backend_decl)) + if ((sym->attr.dimension || sym->attr.codimension) + && !TREE_USED (sym->backend_decl)) { decl = gfc_build_dummy_array_decl (sym, sym->backend_decl); /* Prevent the dummy from being detected as unused if it is copied. */ @@ -1243,7 +1246,7 @@ gfc_get_symbol_decl (gfc_symbol * sym) gfc_add_assign_aux_vars (sym); } - if (sym->attr.dimension + if ((sym->attr.dimension || sym->attr.codimension) && DECL_LANG_SPECIFIC (sym->backend_decl) && GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl) && DECL_CONTEXT (sym->backend_decl) != current_function_decl) @@ -1316,7 +1319,7 @@ gfc_get_symbol_decl (gfc_symbol * sym) DECL_IGNORED_P (decl) = 1; } - if (sym->attr.dimension) + if (sym->attr.dimension || sym->attr.codimension) { /* Create variables to hold the non-constant bits of array info. */ gfc_build_qualified_array (decl, sym); @@ -1327,7 +1330,7 @@ gfc_get_symbol_decl (gfc_symbol * sym) } /* Remember this variable for allocation/cleanup. */ - if (sym->attr.dimension || sym->attr.allocatable + if (sym->attr.dimension || sym->attr.codimension || sym->attr.allocatable || (sym->ts.type == BT_CLASS && (CLASS_DATA (sym)->attr.dimension || CLASS_DATA (sym)->attr.allocatable)) @@ -2033,7 +2036,7 @@ create_function_arglist (gfc_symbol * sym) /* For non-constant length array arguments, make sure they use a different type node from TYPE_ARG_TYPES type. */ - if (f->sym->attr.dimension + if ((f->sym->attr.dimension||f->sym->attr.codimension) && type == TREE_VALUE (typelist) && TREE_CODE (type) == POINTER_TYPE && GFC_ARRAY_TYPE_P (type) @@ -3435,7 +3438,7 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block) if (sym->assoc) continue; - if (sym->attr.dimension) + if (sym->attr.dimension || sym->attr.codimension) { switch (sym->as->type) { diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 22a2c5b..bd2261b 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1111,8 +1111,16 @@ gfc_get_element_type (tree type) { if (TREE_CODE (type) == POINTER_TYPE) type = TREE_TYPE (type); - gcc_assert (TREE_CODE (type) == ARRAY_TYPE); - element = TREE_TYPE (type); + if (GFC_TYPE_ARRAY_RANK (type) == 0) + { + gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0); + element = type; + } + else + { + gcc_assert (TREE_CODE (type) == ARRAY_TYPE); + element = TREE_TYPE (type); + } } else { @@ -1423,7 +1431,19 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, /* We don't use build_array_type because this does not include include lang-specific information (i.e. the bounds of the array) when checking for duplicates. */ - type = make_node (ARRAY_TYPE); + if (as->rank) + type = make_node (ARRAY_TYPE); + else + { + type = make_node (TREE_CODE (etype)); + TREE_TYPE (type) = etype; + TYPE_PRECISION (type) = TYPE_PRECISION (etype); + SET_TYPE_MODE (type, TYPE_MODE (etype)); + TYPE_SIZE (type) = TYPE_SIZE (etype); + TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (etype); + TYPE_ALIGN (type) = TYPE_ALIGN (etype); + TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (etype); + } GFC_ARRAY_TYPE_P (type) = 1; TYPE_LANG_SPECIFIC (type) @@ -1537,6 +1557,23 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, build_qualified_type (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), TYPE_QUAL_RESTRICT); + if (as->rank == 0) + { + if (packed != PACKED_STATIC) + type = build_pointer_type (type); + + if (restricted) + type = build_qualified_type (type, TYPE_QUAL_RESTRICT); + + if (packed != PACKED_STATIC) + { + GFC_ARRAY_TYPE_P (type) = 1; + TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type)); + } + + return type; + } + if (known_stride) { mpz_sub_ui (stride, stride, 1); @@ -1550,7 +1587,6 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, build_pointer_type (etype); TREE_TYPE (type) = etype; - layout_type (type); mpz_clear (offset); @@ -1694,9 +1730,10 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, stride = gfc_index_one_node; else stride = NULL_TREE; - for (n = 0; n < dimen; n++) + for (n = 0; n < dimen + codimen; n++) { - GFC_TYPE_ARRAY_STRIDE (fat_type, n) = stride; + if (n < dimen) + GFC_TYPE_ARRAY_STRIDE (fat_type, n) = stride; if (lbound) lower = lbound[n]; @@ -1711,6 +1748,9 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, lower = NULL_TREE; } + if (codimen && n == dimen + codimen - 1) + break; + upper = ubound[n]; if (upper != NULL_TREE) { @@ -1720,6 +1760,9 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, upper = NULL_TREE; } + if (n >= dimen) + continue; + if (upper != NULL_TREE && lower != NULL_TREE && stride != NULL_TREE) { tmp = fold_build2_loc (input_location, MINUS_EXPR, diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 1d25cb0..a0c1d5c 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -316,6 +316,12 @@ gfc_build_array_ref (tree base, tree offset, tree decl) tree type = TREE_TYPE (base); tree tmp; + if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0) + { + gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0); + return base; + } + gcc_assert (TREE_CODE (type) == ARRAY_TYPE); type = TREE_TYPE (type);