diff options
author | Tobias Burnus <burnus@net-b.de> | 2010-04-27 10:41:00 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2010-04-27 10:41:00 +0200 |
commit | f33beee9f9213d102fc0b396657e857be3f852b0 (patch) | |
tree | 42b0fbad69c17856b9cdcd2534809988ef7ec0a2 /gcc/fortran | |
parent | d89488ec13d521f894e1d3d3aad05d01940226bb (diff) | |
download | gcc-f33beee9f9213d102fc0b396657e857be3f852b0.zip gcc-f33beee9f9213d102fc0b396657e857be3f852b0.tar.gz gcc-f33beee9f9213d102fc0b396657e857be3f852b0.tar.bz2 |
re PR fortran/18918 (Eventually support Fortran 2008's coarrays [co-arrays])
2010-04-27 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
* resolve.c (resolve_allocate_expr): Allow array coarrays.
* trans-types.h (gfc_get_array_type_bounds): Update prototype.
* trans-types.c (gfc_get_array_type_bounds,
gfc_get_array_descriptor_base): Add corank argument.
* trans-array.c (gfc_array_init_size): Handle corank.
(gfc_trans_create_temp_array, gfc_array_allocate,
gfc_conv_expr_descriptor): Add corank argument to call.
* trans-stmt.c (gfc_trans_pointer_assign_need_temp): Ditto.
2010-04-27 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
* gfortran.dg/coarray_7.f90: Modified and removed obsolete
tests.
* gfortran.dg/coarray_12.f90: New.
From-SVN: r158768
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 4 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 92 | ||||
-rw-r--r-- | gcc/fortran/trans-stmt.c | 2 | ||||
-rw-r--r-- | gcc/fortran/trans-types.c | 26 | ||||
-rw-r--r-- | gcc/fortran/trans-types.h | 2 |
6 files changed, 98 insertions, 40 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a45ba4f..9db6b60 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2010-04-27 Tobias Burnus <burnus@net-b.de> + + PR fortran/18918 + * resolve.c (resolve_allocate_expr): Allow array coarrays. + * trans-types.h (gfc_get_array_type_bounds): Update prototype. + * trans-types.c (gfc_get_array_type_bounds, + gfc_get_array_descriptor_base): Add corank argument. + * trans-array.c (gfc_array_init_size): Handle corank. + (gfc_trans_create_temp_array, gfc_array_allocate, + gfc_conv_expr_descriptor): Add corank argument to call. + * trans-stmt.c (gfc_trans_pointer_assign_need_temp): Ditto. + 2010-04-24 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/30073 diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index aeccffb..135eda4 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -6561,9 +6561,9 @@ check_symbols: goto failure; } - if (codimension) + if (codimension && ar->as->rank == 0) { - gfc_error ("Sorry, allocatable coarrays are no yet supported coarray " + gfc_error ("Sorry, allocatable scalar coarrays are not yet supported " "at %L", &e->where); goto failure; } diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 1b56189..e20406c 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -725,7 +725,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, /* Initialize the descriptor. */ type = - gfc_get_array_type_bounds (eltype, info->dimen, loop->from, loop->to, 1, + gfc_get_array_type_bounds (eltype, info->dimen, 0, loop->from, loop->to, 1, GFC_ARRAY_UNKNOWN, true); desc = gfc_create_var (type, "atmp"); GFC_DECL_PACKED_ARRAY (desc) = 1; @@ -3819,7 +3819,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where) /*GCC ARRAYS*/ static tree -gfc_array_init_size (tree descriptor, int rank, tree * poffset, +gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset, gfc_expr ** lower, gfc_expr ** upper, stmtblock_t * pblock) { @@ -3917,6 +3917,43 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset, stride = gfc_evaluate_now (stride, pblock); } + for (n = rank; n < rank + corank; n++) + { + ubound = upper[n]; + + /* Set lower bound. */ + gfc_init_se (&se, NULL); + if (lower == NULL || lower[n] == NULL) + { + gcc_assert (n == rank + corank - 1); + se.expr = gfc_index_one_node; + } + else + { + if (ubound || n == rank + corank - 1) + { + gfc_conv_expr_type (&se, lower[n], gfc_array_index_type); + gfc_add_block_to_block (pblock, &se.pre); + } + else + { + se.expr = gfc_index_one_node; + ubound = lower[n]; + } + } + gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n], + se.expr); + + if (n < rank + corank - 1) + { + gfc_init_se (&se, NULL); + gcc_assert (ubound); + gfc_conv_expr_type (&se, ubound, gfc_array_index_type); + gfc_add_block_to_block (pblock, &se.pre); + gfc_conv_descriptor_ubound_set (pblock, descriptor, gfc_rank_cst[n], se.expr); + } + } + /* The stride is the number of elements in the array, so multiply by the size of an element to get the total size. */ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); @@ -3965,7 +4002,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat) gfc_expr **lower; gfc_expr **upper; gfc_ref *ref, *prev_ref = NULL; - bool allocatable_array; + bool allocatable_array, coarray; ref = expr->ref; @@ -3981,29 +4018,40 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat) if (ref == NULL || ref->type != REF_ARRAY) return false; - /* Return if this is a scalar coarray. */ - if (!prev_ref && !expr->symtree->n.sym->attr.dimension) + if (!prev_ref) { - gcc_assert (expr->symtree->n.sym->attr.codimension); - return false; + allocatable_array = expr->symtree->n.sym->attr.allocatable; + coarray = expr->symtree->n.sym->attr.codimension; } - else if (prev_ref && !prev_ref->u.c.component->attr.dimension) + else { - gcc_assert (prev_ref->u.c.component->attr.codimension); - return false; + allocatable_array = prev_ref->u.c.component->attr.allocatable; + coarray = prev_ref->u.c.component->attr.codimension; } - if (!prev_ref) - allocatable_array = expr->symtree->n.sym->attr.allocatable; - else - allocatable_array = prev_ref->u.c.component->attr.allocatable; + /* Return if this is a scalar coarray. */ + if ((!prev_ref && !expr->symtree->n.sym->attr.dimension) + || (prev_ref && !prev_ref->u.c.component->attr.dimension)) + { + gcc_assert (coarray); + return false; + } /* Figure out the size of the array. */ switch (ref->u.ar.type) { case AR_ELEMENT: - lower = NULL; - upper = ref->u.ar.start; + if (!coarray) + { + lower = NULL; + upper = ref->u.ar.start; + break; + } + /* Fall through. */ + + case AR_SECTION: + lower = ref->u.ar.start; + upper = ref->u.ar.end; break; case AR_FULL: @@ -4013,18 +4061,14 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat) upper = ref->u.ar.as->upper; break; - case AR_SECTION: - lower = ref->u.ar.start; - upper = ref->u.ar.end; - break; - default: gcc_unreachable (); break; } - size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, &offset, - lower, upper, &se->pre); + size = gfc_array_init_size (se->expr, ref->u.ar.as->rank, + ref->u.ar.as->corank, &offset, lower, upper, + &se->pre); /* Allocate memory to store the data. */ pointer = gfc_conv_descriptor_data_get (se->expr); @@ -5299,7 +5343,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss) { /* Otherwise make a new one. */ parmtype = gfc_get_element_type (TREE_TYPE (desc)); - parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, + parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0, loop.from, loop.to, 0, GFC_ARRAY_UNKNOWN, false); parm = gfc_create_var (parmtype, "parm"); diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index 0b215f2..edffb9b 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -2822,7 +2822,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2, /* Make a new descriptor. */ parmtype = gfc_get_element_type (TREE_TYPE (desc)); - parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, + parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0, loop.from, loop.to, 1, GFC_ARRAY_UNKNOWN, true); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index e359a48..9d53784 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1222,8 +1222,8 @@ gfc_build_array_type (tree type, gfc_array_spec * as, if (as->type == AS_ASSUMED_SHAPE) akind = GFC_ARRAY_ASSUMED_SHAPE; - return gfc_get_array_type_bounds (type, as->rank, lbound, ubound, 0, akind, - restricted); + return gfc_get_array_type_bounds (type, as->rank, as->corank, lbound, + ubound, 0, akind, restricted); } /* Returns the struct descriptor_dimension type. */ @@ -1538,20 +1538,21 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, /* Return or create the base type for an array descriptor. */ static tree -gfc_get_array_descriptor_base (int dimen, bool restricted) +gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted) { tree fat_type, fieldlist, decl, arraytype; - char name[16 + GFC_RANK_DIGITS + 1]; + char name[16 + 2*GFC_RANK_DIGITS + 1 + 1]; int idx = 2 * (dimen - 1) + restricted; - gcc_assert (dimen >= 1 && dimen <= GFC_MAX_DIMENSIONS); + gcc_assert (dimen >= 1 && codimen + dimen <= GFC_MAX_DIMENSIONS); if (gfc_array_descriptor_base[idx]) return gfc_array_descriptor_base[idx]; /* Build the type node. */ fat_type = make_node (RECORD_TYPE); - sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT, dimen); + sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT "_" + GFC_RANK_PRINTF_FORMAT, dimen, codimen); TYPE_NAME (fat_type) = get_identifier (name); /* Add the data member as the first element of the descriptor. */ @@ -1583,7 +1584,7 @@ gfc_get_array_descriptor_base (int dimen, bool restricted) build_array_type (gfc_get_desc_dim_type (), build_range_type (gfc_array_index_type, gfc_index_zero_node, - gfc_rank_cst[dimen - 1])); + gfc_rank_cst[codimen + dimen - 1])); decl = build_decl (input_location, FIELD_DECL, get_identifier ("dim"), arraytype); @@ -1604,20 +1605,20 @@ gfc_get_array_descriptor_base (int dimen, bool restricted) /* Build an array (descriptor) type with given bounds. */ tree -gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound, +gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, tree * ubound, int packed, enum gfc_array_kind akind, bool restricted) { - char name[8 + GFC_RANK_DIGITS + GFC_MAX_SYMBOL_LEN]; + char name[8 + 2*GFC_RANK_DIGITS + 1 + GFC_MAX_SYMBOL_LEN]; tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype; const char *type_name; int n; - base_type = gfc_get_array_descriptor_base (dimen, restricted); + base_type = gfc_get_array_descriptor_base (dimen, codimen, restricted); fat_type = build_distinct_type_copy (base_type); /* Make sure that nontarget and target array type have the same canonical type (and same stub decl for debug info). */ - base_type = gfc_get_array_descriptor_base (dimen, false); + base_type = gfc_get_array_descriptor_base (dimen, codimen, false); TYPE_CANONICAL (fat_type) = base_type; TYPE_STUB_DECL (fat_type) = TYPE_STUB_DECL (base_type); @@ -1628,7 +1629,8 @@ gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound, type_name = IDENTIFIER_POINTER (tmp); else type_name = "unknown"; - sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen, + sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_" + GFC_RANK_PRINTF_FORMAT "_%.*s", dimen, codimen, GFC_MAX_SYMBOL_LEN, type_name); TYPE_NAME (fat_type) = get_identifier (name); diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h index 87feea3..0b96211 100644 --- a/gcc/fortran/trans-types.h +++ b/gcc/fortran/trans-types.h @@ -72,7 +72,7 @@ tree gfc_type_for_mode (enum machine_mode, int); tree gfc_build_uint_type (int); tree gfc_get_element_type (tree); -tree gfc_get_array_type_bounds (tree, int, tree *, tree *, int, +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); |