diff options
author | Tobias Burnus <burnus@net-b.de> | 2010-04-09 07:54:29 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2010-04-09 07:54:29 +0200 |
commit | d3a9eea2c0e65e0f03c249bab8aa3fa56149dfe0 (patch) | |
tree | c5824608230be7c5a1ca050d3176ffd9450f386d /gcc/fortran/decl.c | |
parent | 824935eed311fc4a22682c800c29737788adfa26 (diff) | |
download | gcc-d3a9eea2c0e65e0f03c249bab8aa3fa56149dfe0.zip gcc-d3a9eea2c0e65e0f03c249bab8aa3fa56149dfe0.tar.gz gcc-d3a9eea2c0e65e0f03c249bab8aa3fa56149dfe0.tar.bz2 |
re PR fortran/18918 (Eventually support Fortran 2008's coarrays [co-arrays])
2010-04-09 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
* decl.c (variable_decl, match_attr_spec): Fix setting the array
spec.
* array.c (match_subscript,gfc_match_array_ref): Add coarray
* support.
* data.c (gfc_assign_data_value): Ditto.
* expr.c (gfc_check_pointer_assign): Add check for coarray
* constraint.
(gfc_traverse_expr): Traverse also through codimension expressions.
(gfc_is_coindexed, gfc_has_ultimate_allocatable,
gfc_has_ultimate_pointer): New functions.
* gfortran.h (gfc_array_ref_dimen_type): Add DIMEN_STAR for
* coarrays.
(gfc_array_ref): Add codimen.
(gfc_array_ref): Add in_allocate.
(gfc_is_coindexed, gfc_has_ultimate_allocatable,
gfc_has_ultimate_pointer): Add prototypes.
* interface.c (compare_parameter, compare_actual_formal,
check_intents): Add coarray constraints.
* match.c (gfc_match_iterator): Add coarray constraint.
* match.h (gfc_match_array_ref): Update interface.
* primary.c (gfc_match_varspec): Handle codimensions.
* resolve.c (coarray_alloc, inquiry_argument): New static
* variables.
(check_class_members): Return gfc_try instead for error recovery.
(resolve_typebound_function,resolve_typebound_subroutine,
check_members): Handle return value of check_class_members.
(resolve_structure_cons, resolve_actual_arglist, resolve_function,
check_dimension, compare_spec_to_ref, resolve_array_ref,
resolve_ref, resolve_variable, gfc_resolve_expr, conformable_arrays,
resolve_allocate_expr, resolve_ordinary_assign): Add coarray
support.
* trans-array.c (gfc_conv_array_ref, gfc_walk_variable_expr):
Skip over coarray refs.
(gfc_array_allocate) Add support for references containing coindexes.
* trans-expr.c (gfc_add_interface_mapping): Copy coarray
* attribute.
(gfc_map_intrinsic_function): Ignore codimensions.
2010-04-09 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
* gfortran.dg/coarray_7.f90: New test.
* gfortran.dg/coarray_8.f90: New test.
From-SVN: r158149
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r-- | gcc/fortran/decl.c | 86 |
1 files changed, 72 insertions, 14 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index b376192..a9cd984 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -570,6 +570,62 @@ cleanup: /************************ Declaration statements *********************/ + +/* Auxilliary function to merge DIMENSION and CODIMENSION array specs. */ + +static void +merge_array_spec (gfc_array_spec *from, gfc_array_spec *to, bool copy) +{ + int i; + + if (to->rank == 0 && from->rank > 0) + { + to->rank = from->rank; + to->type = from->type; + to->cray_pointee = from->cray_pointee; + to->cp_was_assumed = from->cp_was_assumed; + + for (i = 0; i < to->corank; i++) + { + to->lower[from->rank + i] = to->lower[i]; + to->upper[from->rank + i] = to->upper[i]; + } + for (i = 0; i < from->rank; i++) + { + if (copy) + { + to->lower[i] = gfc_copy_expr (from->lower[i]); + to->upper[i] = gfc_copy_expr (from->upper[i]); + } + else + { + to->lower[i] = from->lower[i]; + to->upper[i] = from->upper[i]; + } + } + } + else if (to->corank == 0 && from->corank > 0) + { + to->corank = from->corank; + to->cotype = from->cotype; + + for (i = 0; i < from->corank; i++) + { + if (copy) + { + to->lower[to->rank + i] = gfc_copy_expr (from->lower[i]); + to->upper[to->rank + i] = gfc_copy_expr (from->upper[i]); + } + else + { + to->lower[to->rank + i] = from->lower[i]; + to->upper[to->rank + i] = from->upper[i]; + } + } + } +} + + /* Match an intent specification. Since this can only happen after an INTENT word, a legal intent-spec must follow. */ @@ -1603,6 +1659,8 @@ variable_decl (int elem) if (m == MATCH_NO) as = gfc_copy_array_spec (current_as); + else if (current_as) + merge_array_spec (current_as, as, true); char_len = NULL; cl = NULL; @@ -3050,27 +3108,27 @@ match_attr_spec (void) seen[d]++; seen_at[d] = gfc_current_locus; - if (d == DECL_DIMENSION) + if (d == DECL_DIMENSION || d == DECL_CODIMENSION) { - m = gfc_match_array_spec (¤t_as, true, false); + gfc_array_spec *as = NULL; - if (m == MATCH_NO) + m = gfc_match_array_spec (&as, d == DECL_DIMENSION, + d == DECL_CODIMENSION); + + if (current_as == NULL) + current_as = as; + else if (m == MATCH_YES) { - gfc_error ("Missing dimension specification at %C"); - m = MATCH_ERROR; + merge_array_spec (as, current_as, false); + gfc_free (as); } - if (m == MATCH_ERROR) - goto cleanup; - } - - if (d == DECL_CODIMENSION) - { - m = gfc_match_array_spec (¤t_as, false, true); - if (m == MATCH_NO) { - gfc_error ("Missing codimension specification at %C"); + if (d == DECL_CODIMENSION) + gfc_error ("Missing codimension specification at %C"); + else + gfc_error ("Missing dimension specification at %C"); m = MATCH_ERROR; } |