Hi all, attached patch fixes an addressing issue for coarrays *in* derived types. Before the patch the caf runtime reference chain was generated from the start of the symbol to the last reference *and* the reference chain upto the coarray in the derived type was used to call the caf_*_by_ref () functions. The patch fixes this by skipping the generation of unnecessary caf runtime references.
The second part fixes finding the token for coarrayed arrays. The new semantic is, that each allocatable array has the coarray token in its .token member, which the allocate_array now makes use of. Bootstrapped and regtested ok on x86_64-linux/F23. Ok for trunk? Regards, Andre -- Andre Vehreschild * Email: vehre ad gmx dot de
gcc/fortran/ChangeLog: 2016-09-29 Andre Vehreschild <ve...@gcc.gnu.org> * trans-array.c (gfc_array_allocate): Use the token from coarray's .token member. * trans-intrinsic.c (conv_expr_ref_to_caf_ref): Only generate caf-reference chains from the first coarray references on. * trans-types.c (gfc_get_derived_type): Switch on mandatory .token member generation for allocatable arrays in coarrays in derived types. gcc/testsuite/ChangeLog: 2016-09-29 Andre Vehreschild <ve...@gcc.gnu.org> * gfortran.dg/coarray_allocate_10.f08: New test. * gfortran.dg/coindexed_1.f90: Above fixes allow execution.
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 0b97760..50312fe 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -5406,7 +5406,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, gfc_expr **lower; gfc_expr **upper; gfc_ref *ref, *prev_ref = NULL, *coref; - gfc_se caf_se; bool allocatable, coarray, dimension, alloc_w_e3_arr_spec = false; ref = expr->ref; @@ -5531,7 +5530,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, } } - gfc_init_se (&caf_se, NULL); gfc_start_block (&elseblock); /* Allocate memory to store the data. */ @@ -5543,9 +5541,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, if (coarray && flag_coarray == GFC_FCOARRAY_LIB) { - tmp = gfc_get_tree_for_caf_expr (expr); - gfc_get_caf_token_offset (&caf_se, &token, NULL, tmp, NULL_TREE, expr); - gfc_add_block_to_block (&elseblock, &caf_se.pre); + token = gfc_conv_descriptor_token (se->expr); token = gfc_build_addr_expr (NULL_TREE, token); } @@ -5557,7 +5553,6 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, else gfc_allocate_using_malloc (&elseblock, pointer, size, status); - gfc_add_block_to_block (&elseblock, &caf_se.post); if (dimension) { cond = gfc_unlikely (fold_build2_loc (input_location, NE_EXPR, diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 954f7b3..a499c32 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -1110,7 +1110,7 @@ compute_component_offset (tree field, tree type) static tree conv_expr_ref_to_caf_ref (stmtblock_t *block, gfc_expr *expr) { - gfc_ref *ref = expr->ref; + gfc_ref *ref = expr->ref, *last_comp_ref; tree caf_ref = NULL_TREE, prev_caf_ref = NULL_TREE, reference_type, tmp, tmp2, field, last_type, inner_struct, mode, mode_rhs, dim_array, dim, dim_type, start, end, stride, vector, nvec; @@ -1127,8 +1127,29 @@ conv_expr_ref_to_caf_ref (stmtblock_t *block, gfc_expr *expr) /* Prevent uninit-warning. */ reference_type = NULL_TREE; - last_type = gfc_typenode_for_spec (&expr->symtree->n.sym->ts); - last_type_n = expr->symtree->n.sym->ts.type; + + /* Skip refs upto the first coarray-ref. */ + last_comp_ref = NULL; + while (ref && (ref->type != REF_ARRAY || ref->u.ar.codimen == 0)) + { + /* Remember the type of components skipped. */ + if (ref->type == REF_COMPONENT) + last_comp_ref = ref; + ref = ref->next; + } + /* When a component was skipped, get the type information of the last + component ref, else get the type from the symbol. */ + if (last_comp_ref) + { + last_type = gfc_typenode_for_spec (&last_comp_ref->u.c.component->ts); + last_type_n = last_comp_ref->u.c.component->ts.type; + } + else + { + last_type = gfc_typenode_for_spec (&expr->symtree->n.sym->ts); + last_type_n = expr->symtree->n.sym->ts.type; + } + while (ref) { if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0 diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 27a6bab..05122d9 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -2565,7 +2565,8 @@ gfc_get_derived_type (gfc_symbol * derived, bool in_coarray) if ((!c->attr.pointer && !c->attr.proc_pointer) || c->ts.u.derived->backend_decl == NULL) c->ts.u.derived->backend_decl = gfc_get_derived_type (c->ts.u.derived, - in_coarray); + in_coarray + || c->attr.codimension); if (c->ts.u.derived->attr.is_iso_c) { diff --git a/gcc/testsuite/gfortran.dg/coarray_allocate_10.f08 b/gcc/testsuite/gfortran.dg/coarray_allocate_10.f08 new file mode 100644 index 0000000..30ee216 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coarray_allocate_10.f08 @@ -0,0 +1,39 @@ +! { dg-do run } +! { dg-options "-fcoarray=lib -lcaf_single" } + +program alloc_comp + implicit none + + type coords + integer,allocatable :: x(:) + end type + + type outerT + type(coords),allocatable :: coo[:] + end type + integer :: me,np,n,i + type(outerT) :: o + + ! with caf_single num_images is always == 1 + me = this_image(); np = num_images() + n = 100 + + allocate(o%coo[*]) + allocate(o%coo%x(n)) + + o%coo%x = me + + do i=1, n + o%coo%x(i) = o%coo%x(i) + i + end do + + sync all + + if(me == 1 .and. o%coo[np]%x(10) /= 11 ) call abort() + + ! Check the whole array is correct. + if (me == 1 .and. any( o%coo[np]%x /= [(i, i=2, 101)] ) ) call abort() + + deallocate(o%coo%x) + +end program diff --git a/gcc/testsuite/gfortran.dg/coindexed_1.f90 b/gcc/testsuite/gfortran.dg/coindexed_1.f90 index b25f2f8..932442c 100644 --- a/gcc/testsuite/gfortran.dg/coindexed_1.f90 +++ b/gcc/testsuite/gfortran.dg/coindexed_1.f90 @@ -1,5 +1,5 @@ -! { dg-do compile } -! { dg-options "-fcoarray=lib" } +! { dg-do run } +! { dg-options "-fcoarray=lib -lcaf_single" } ! ! Contributed by Reinhold Bader ! @@ -14,7 +14,7 @@ program pmup integer :: ii !! --- ONE --- - allocate(real :: a(3)[*]) ! { dg-error "Sorry, coindexed access to an unlimited polymorphic object at" } + allocate(real :: a(3)[*]) IF (this_image() == num_images()) THEN SELECT TYPE (a) TYPE IS (real) @@ -43,7 +43,7 @@ program pmup !! --- TWO --- deallocate(a) - allocate(t :: a(3)[*]) ! { dg-error "Sorry, coindexed access to an unlimited polymorphic object at" } + allocate(t :: a(3)[*]) IF (this_image() == num_images()) THEN SELECT TYPE (a) TYPE IS (t)