diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index abc3383..b744a21 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -6189,7 +6189,7 @@ gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub) int d; if (!is_constant_array_expr (sub)) - goto not_implemented; /* return NULL;*/ + return NULL; /* Follow any component references. */ as = coarray->symtree->n.sym->as; @@ -6198,7 +6198,7 @@ gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub) as = ref->u.ar.as; if (as->type == AS_DEFERRED) - goto not_implemented; /* return NULL;*/ + return NULL; /* "valid sequence of cosubscripts" are required; thus, return 0 unless the cosubscript addresses the first image. */ @@ -6221,7 +6221,7 @@ gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub) ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 0, as, NULL, true); if (ca_bound == NULL) - goto not_implemented; /* return NULL */ + return NULL; if (ca_bound == &gfc_bad_expr) return ca_bound; @@ -6285,6 +6285,10 @@ gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub) return &gfc_bad_expr; } + + if (gfc_option.coarray != GFC_FCOARRAY_SINGLE && !first_image) + return NULL; + result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind, &gfc_current_locus); if (first_image) @@ -6293,11 +6297,6 @@ gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub) mpz_set_si (result->value.integer, 0); return result; - -not_implemented: - gfc_error ("Not yet implemented: IMAGE_INDEX for coarray with non-constant " - "cobounds at %L", &coarray->where); - return &gfc_bad_expr; } diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index b4cc360..9853686 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -929,6 +929,60 @@ trans_this_image (gfc_se * se, gfc_expr *expr ATTRIBUTE_UNUSED) } static void +trans_image_index (gfc_se * se, gfc_expr *expr ATTRIBUTE_UNUSED) +{ + tree num_images, cond, coindex, type, lbound, desc; + gfc_se argse; + gfc_ss *ss; + int rank, corank; + + type = gfc_get_int_type (gfc_default_integer_kind); + corank = gfc_get_corank (expr->value.function.actual->expr); + rank = expr->value.function.actual->expr->rank; + + gfc_init_se (&argse, NULL); + ss = gfc_walk_expr (expr->value.function.actual->expr); + gcc_assert (ss != gfc_ss_terminator); + argse.want_pointer = 1; + argse.data_not_needed = 1; + gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss); + gfc_add_block_to_block (&se->pre, &argse.pre); + gfc_add_block_to_block (&se->post, &argse.post); + desc = argse.expr; + + /* See Fortran 2008, C.10 for the algorithm. */ + + /* coindex = sub(corank) - lcobound(n). */ + coindex = NULL_TREE; /*FIXME: Use algorithm. */ + lbound = gfc_conv_descriptor_lbound_get (desc, + build_int_cst (gfc_array_index_type, rank+corank-1)); + coindex = lbound; + +/* + for (codim = corank + rank - 2; codim >= rank; codim--) + { +*/ /* coindex = coindex*extend(codim) + sub(codim) - lcobound(codim). */ +/* gfc_conv_descriptor_cosize (desc, codim, codim) + } +*/ + coindex = fold_build2_loc (input_location, PLUS_EXPR, type, + coindex, build_int_cst (type, 1)); + + if (gfc_option.coarray == GFC_FCOARRAY_SINGLE) + num_images = build_int_cst (type, 0); + else + { + gfc_init_coarray_decl (); + num_images = gfort_gvar_caf_num_images; + } + + cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, coindex, + num_images); + se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, coindex, + build_int_cst (type, 0)); +} + +static void trans_num_images (gfc_se * se) { gfc_init_coarray_decl (); @@ -6316,6 +6370,9 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr) trans_this_image (se, expr); break; + case GFC_ISYM_IMAGE_INDEX: + trans_image_index (se, expr); + case GFC_ISYM_NUM_IMAGES: trans_num_images (se); break;