Skip to content

Commit 9ead532

Browse files
author
pault
committed
2017-11-19 Paul Thomas <[email protected]>
PR fortran/78990 * expr.c (gfc_is_class_array_function): Renamed from 'gfc_is_alloc_class_array_function' and modified to return true for pointers as well as allocatable results. * gfortran.h : Change of name for prototype of above function. * trans-array.c (gfc_add_loop_ss_code): Force finalization of class array results. (build_class_array_ref): Change assertion into a condition. (build_class_array_ref): Set the se class_vptr for class array function results. (gfc_walk_function_expr): Reference gfc_is_class_array_function as above. * trans-decl.c (get_proc_result): Move it up before gfc_trans_deferred_vars. (gfc_trans_deferred_vars): Nullify explicit return class arrays on entry. * trans-expr.c (gfc_conv_class_to_class): Allow conversion of class array functions that have an se class_vptr and use it for the result vptr. (gfc_conv_subref_array_arg): Rename reference to the above function. (gfc_conv_procedure_call): Ditto. Add the se pre block to the loop pre block before the function is evaluated. Do not finalize class pointer results. (arrayfunc_assign_needs_temporary, gfc_trans_assignment_1) More renamed references. * trans-intrinsic.c (gfc_conv_intrinsic_size): Ditto. 2017-11-19 Paul Thomas <[email protected]> PR fortran/78990 * gfortran.dg/class_67.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254936 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent e1364c6 commit 9ead532

File tree

10 files changed

+168
-38
lines changed

10 files changed

+168
-38
lines changed

gcc/fortran/ChangeLog

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,33 @@
1+
2017-11-19 Paul Thomas <[email protected]>
2+
3+
PR fortran/78990
4+
* expr.c (gfc_is_class_array_function): Renamed from
5+
'gfc_is_alloc_class_array_function' and modified to return true
6+
for pointers as well as allocatable results.
7+
* gfortran.h : Change of name for prototype of above function.
8+
* trans-array.c (gfc_add_loop_ss_code): Force finalization of
9+
class array results.
10+
(build_class_array_ref): Change assertion into a condition.
11+
(build_class_array_ref): Set the se class_vptr for class array
12+
function results.
13+
(gfc_walk_function_expr): Reference gfc_is_class_array_function
14+
as above.
15+
* trans-decl.c (get_proc_result): Move it up before
16+
gfc_trans_deferred_vars.
17+
(gfc_trans_deferred_vars): Nullify explicit return class arrays
18+
on entry.
19+
* trans-expr.c (gfc_conv_class_to_class): Allow conversion of
20+
class array functions that have an se class_vptr and use it
21+
for the result vptr.
22+
(gfc_conv_subref_array_arg): Rename reference to the above
23+
function.
24+
(gfc_conv_procedure_call): Ditto. Add the se pre block to the
25+
loop pre block before the function is evaluated. Do not
26+
finalize class pointer results.
27+
(arrayfunc_assign_needs_temporary, gfc_trans_assignment_1) More
28+
renamed references.
29+
* trans-intrinsic.c (gfc_conv_intrinsic_size): Ditto.
30+
131
2017-11-18 Janne Blomqvist <[email protected]>
232

333
PR fortran/83036

gcc/fortran/expr.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4844,14 +4844,15 @@ gfc_is_alloc_class_scalar_function (gfc_expr *expr)
48444844
/* Determine if an expression is a function with an allocatable class array
48454845
result. */
48464846
bool
4847-
gfc_is_alloc_class_array_function (gfc_expr *expr)
4847+
gfc_is_class_array_function (gfc_expr *expr)
48484848
{
48494849
if (expr->expr_type == EXPR_FUNCTION
48504850
&& expr->value.function.esym
48514851
&& expr->value.function.esym->result
48524852
&& expr->value.function.esym->result->ts.type == BT_CLASS
48534853
&& CLASS_DATA (expr->value.function.esym->result)->attr.dimension
4854-
&& CLASS_DATA (expr->value.function.esym->result)->attr.allocatable)
4854+
&& (CLASS_DATA (expr->value.function.esym->result)->attr.allocatable
4855+
|| CLASS_DATA (expr->value.function.esym->result)->attr.pointer))
48554856
return true;
48564857

48574858
return false;

gcc/fortran/gfortran.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3195,7 +3195,7 @@ gfc_param_spec_type gfc_spec_list_type (gfc_actual_arglist *, gfc_symbol *);
31953195
gfc_component * gfc_get_proc_ptr_comp (gfc_expr *);
31963196
bool gfc_is_proc_ptr_comp (gfc_expr *);
31973197
bool gfc_is_alloc_class_scalar_function (gfc_expr *);
3198-
bool gfc_is_alloc_class_array_function (gfc_expr *);
3198+
bool gfc_is_class_array_function (gfc_expr *);
31993199

32003200
bool gfc_ref_this_image (gfc_ref *ref);
32013201
bool gfc_is_coindexed (gfc_expr *);

gcc/fortran/resolve.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8740,6 +8740,9 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
87408740
code->expr1->symtree->n.sym->ts = code->expr2->ts;
87418741
selector_type = CLASS_DATA (code->expr2)->ts.u.derived;
87428742

8743+
if (code->expr2->rank && CLASS_DATA (code->expr1)->as)
8744+
CLASS_DATA (code->expr1)->as->rank = code->expr2->rank;
8745+
87438746
/* F2008: C803 The selector expression must not be coindexed. */
87448747
if (gfc_is_coindexed (code->expr2))
87458748
{

gcc/fortran/trans-array.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2791,6 +2791,8 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
27912791
gfc_init_se (&se, NULL);
27922792
se.loop = loop;
27932793
se.ss = ss;
2794+
if (gfc_is_class_array_function (expr))
2795+
expr->must_finalize = 1;
27942796
gfc_conv_expr (&se, expr);
27952797
gfc_add_block_to_block (&outer_loop->pre, &se.pre);
27962798
gfc_add_block_to_block (&outer_loop->post, &se.post);
@@ -3241,7 +3243,7 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
32413243
{
32423244
if (expr == NULL
32433245
|| (expr->ts.type != BT_CLASS
3244-
&& !gfc_is_alloc_class_array_function (expr)
3246+
&& !gfc_is_class_array_function (expr)
32453247
&& !gfc_is_class_array_ref (expr, NULL)))
32463248
return false;
32473249

@@ -3271,12 +3273,12 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
32713273
}
32723274

32733275
if (class_ref == NULL && expr && expr->symtree->n.sym->attr.function
3274-
&& expr->symtree->n.sym == expr->symtree->n.sym->result)
3276+
&& expr->symtree->n.sym == expr->symtree->n.sym->result
3277+
&& expr->symtree->n.sym->backend_decl == current_function_decl)
32753278
{
3276-
gcc_assert (expr->symtree->n.sym->backend_decl == current_function_decl);
32773279
decl = gfc_get_fake_result_decl (expr->symtree->n.sym, 0);
32783280
}
3279-
else if (expr && gfc_is_alloc_class_array_function (expr))
3281+
else if (expr && gfc_is_class_array_function (expr))
32803282
{
32813283
size = NULL_TREE;
32823284
decl = NULL_TREE;
@@ -3299,6 +3301,8 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
32993301

33003302
if (decl == NULL_TREE)
33013303
return false;
3304+
3305+
se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre);
33023306
}
33033307
else if (class_ref == NULL)
33043308
{
@@ -10527,7 +10531,7 @@ gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
1052710531
if (!sym)
1052810532
sym = expr->symtree->n.sym;
1052910533

10530-
if (gfc_is_alloc_class_array_function (expr))
10534+
if (gfc_is_class_array_function (expr))
1053110535
return gfc_get_array_ss (ss, expr,
1053210536
CLASS_DATA (expr->value.function.esym->result)->as->rank,
1053310537
GFC_SS_FUNCTION);

gcc/fortran/trans-decl.c

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4161,6 +4161,24 @@ gfc_null_and_pass_deferred_len (gfc_symbol *sym, stmtblock_t *init,
41614161
return tmp;
41624162
}
41634163

4164+
4165+
/* Get the result expression for a procedure. */
4166+
4167+
static tree
4168+
get_proc_result (gfc_symbol* sym)
4169+
{
4170+
if (sym->attr.subroutine || sym == sym->result)
4171+
{
4172+
if (current_fake_result_decl != NULL)
4173+
return TREE_VALUE (current_fake_result_decl);
4174+
4175+
return NULL_TREE;
4176+
}
4177+
4178+
return sym->result->backend_decl;
4179+
}
4180+
4181+
41644182
/* Generate function entry and exit code, and add it to the function body.
41654183
This includes:
41664184
Allocation and initialization of array variables.
@@ -4271,6 +4289,21 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
42714289
else
42724290
gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX);
42734291
}
4292+
else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym))
4293+
{
4294+
/* Nullify explicit return class arrays on entry. */
4295+
tree type;
4296+
tmp = get_proc_result (proc_sym);
4297+
if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
4298+
{
4299+
gfc_start_block (&init);
4300+
tmp = gfc_class_data_get (tmp);
4301+
type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp));
4302+
gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0));
4303+
gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4304+
}
4305+
}
4306+
42744307

42754308
/* Initialize the INTENT(OUT) derived type dummy arguments. This
42764309
should be done here so that the offsets and lbounds of arrays
@@ -6067,23 +6100,6 @@ create_main_function (tree fndecl)
60676100
}
60686101

60696102

6070-
/* Get the result expression for a procedure. */
6071-
6072-
static tree
6073-
get_proc_result (gfc_symbol* sym)
6074-
{
6075-
if (sym->attr.subroutine || sym == sym->result)
6076-
{
6077-
if (current_fake_result_decl != NULL)
6078-
return TREE_VALUE (current_fake_result_decl);
6079-
6080-
return NULL_TREE;
6081-
}
6082-
6083-
return sym->result->backend_decl;
6084-
}
6085-
6086-
60876103
/* Generate an appropriate return-statement for a procedure. */
60886104

60896105
tree

gcc/fortran/trans-expr.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
960960
}
961961

962962
if ((ref == NULL || class_ref == ref)
963+
&& !(gfc_is_class_array_function (e) && parmse->class_vptr != NULL_TREE)
963964
&& (!class_ts.u.derived->components->as
964965
|| class_ts.u.derived->components->as->rank != -1))
965966
return;
@@ -1030,8 +1031,11 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
10301031
First we have to find the corresponding class reference. */
10311032

10321033
tmp = NULL_TREE;
1033-
if (class_ref == NULL
1034-
&& e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
1034+
if (gfc_is_class_array_function (e)
1035+
&& parmse->class_vptr != NULL_TREE)
1036+
tmp = parmse->class_vptr;
1037+
else if (class_ref == NULL
1038+
&& e->symtree && e->symtree->n.sym->ts.type == BT_CLASS)
10351039
{
10361040
tmp = e->symtree->n.sym->backend_decl;
10371041

@@ -1063,7 +1067,11 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts,
10631067
if (TREE_CODE (TREE_TYPE (tmp)) == REFERENCE_TYPE)
10641068
tmp = build_fold_indirect_ref_loc (input_location, tmp);
10651069

1066-
vptr = gfc_class_vptr_get (tmp);
1070+
if (!(gfc_is_class_array_function (e) && parmse->class_vptr))
1071+
vptr = gfc_class_vptr_get (tmp);
1072+
else
1073+
vptr = tmp;
1074+
10671075
gfc_add_modify (&block, ctree,
10681076
fold_convert (TREE_TYPE (ctree), vptr));
10691077

@@ -4435,7 +4443,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
44354443
/* Reset the offset for the function call since the loop
44364444
is zero based on the data pointer. Note that the temp
44374445
comes first in the loop chain since it is added second. */
4438-
if (gfc_is_alloc_class_array_function (expr))
4446+
if (gfc_is_class_array_function (expr))
44394447
{
44404448
tmp = loop.ss->loop_chain->info->data.array.descriptor;
44414449
gfc_conv_descriptor_offset_set (&loop.pre, tmp,
@@ -4484,7 +4492,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr, int g77,
44844492
dimen = rse.ss->dimen;
44854493

44864494
/* Skip the write-out loop for this case. */
4487-
if (gfc_is_alloc_class_array_function (expr))
4495+
if (gfc_is_class_array_function (expr))
44884496
goto class_array_fcn;
44894497

44904498
/* Calculate the bounds of the scalarization. */
@@ -4778,7 +4786,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
47784786
gcc_assert ((!comp && gfc_return_by_reference (sym)
47794787
&& sym->result->attr.dimension)
47804788
|| (comp && comp->attr.dimension)
4781-
|| gfc_is_alloc_class_array_function (expr));
4789+
|| gfc_is_class_array_function (expr));
47824790
gcc_assert (se->loop != NULL);
47834791
/* Access the previously obtained result. */
47844792
gfc_conv_tmp_array_ref (se);
@@ -5462,7 +5470,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
54625470
fsym ? fsym->attr.intent : INTENT_INOUT,
54635471
fsym && fsym->attr.pointer);
54645472

5465-
else if (gfc_is_alloc_class_array_function (e)
5473+
else if (gfc_is_class_array_function (e)
54665474
&& fsym && fsym->ts.type == BT_DERIVED)
54675475
/* See previous comment. For function actual argument,
54685476
the write out is not needed so the intent is set as
@@ -6304,7 +6312,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
63046312
call the finalization function of the temporary. Note that the
63056313
nullification of allocatable components needed by the result
63066314
is done in gfc_trans_assignment_1. */
6307-
if (expr && ((gfc_is_alloc_class_array_function (expr)
6315+
if (expr && ((gfc_is_class_array_function (expr)
63086316
&& se->ss && se->ss->loop)
63096317
|| gfc_is_alloc_class_scalar_function (expr))
63106318
&& se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
@@ -6315,6 +6323,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
63156323
int n;
63166324
if (se->ss && se->ss->loop)
63176325
{
6326+
gfc_add_block_to_block (&se->ss->loop->pre, &se->pre);
63186327
se->expr = gfc_evaluate_now (se->expr, &se->ss->loop->pre);
63196328
tmp = gfc_class_data_get (se->expr);
63206329
info->descriptor = tmp;
@@ -6337,6 +6346,11 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
63376346
CLASS_DATA (expr->value.function.esym->result)->attr);
63386347
}
63396348

6349+
if ((gfc_is_class_array_function (expr)
6350+
|| gfc_is_alloc_class_scalar_function (expr))
6351+
&& CLASS_DATA (expr->value.function.esym->result)->attr.pointer)
6352+
goto no_finalization;
6353+
63406354
final_fndecl = gfc_class_vtab_final_get (se->expr);
63416355
is_final = fold_build2_loc (input_location, NE_EXPR,
63426356
logical_type_node,
@@ -6367,6 +6381,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
63676381
tmp = gfc_call_free (tmp);
63686382
gfc_add_expr_to_block (&se->post, tmp);
63696383
}
6384+
6385+
no_finalization:
63706386
expr->must_finalize = 0;
63716387
}
63726388

@@ -8887,7 +8903,7 @@ arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
88878903
gfc_symbol *sym = expr1->symtree->n.sym;
88888904

88898905
/* Play it safe with class functions assigned to a derived type. */
8890-
if (gfc_is_alloc_class_array_function (expr2)
8906+
if (gfc_is_class_array_function (expr2)
88918907
&& expr1->ts.type == BT_DERIVED)
88928908
return true;
88938909

@@ -9894,7 +9910,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
98949910
rss = NULL;
98959911

98969912
if ((expr1->ts.type == BT_DERIVED)
9897-
&& (gfc_is_alloc_class_array_function (expr2)
9913+
&& (gfc_is_class_array_function (expr2)
98989914
|| gfc_is_alloc_class_scalar_function (expr2)))
98999915
expr2->must_finalize = 1;
99009916

@@ -10101,7 +10117,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
1010110117
a scalar to array assignment, this is done in gfc_trans_scalar_assign
1010210118
as part of the deep copy. */
1010310119
if (!scalar_to_array && expr1->ts.type == BT_DERIVED
10104-
&& (gfc_is_alloc_class_array_function (expr2)
10120+
&& (gfc_is_class_array_function (expr2)
1010510121
|| gfc_is_alloc_class_scalar_function (expr2)))
1010610122
{
1010710123
tmp = rse.expr;

gcc/fortran/trans-intrinsic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6603,7 +6603,7 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
66036603
gfc_add_class_array_ref (actual->expr);
66046604

66056605
argse.data_not_needed = 1;
6606-
if (gfc_is_alloc_class_array_function (actual->expr))
6606+
if (gfc_is_class_array_function (actual->expr))
66076607
{
66086608
/* For functions that return a class array conv_expr_descriptor is not
66096609
able to get the descriptor right. Therefore this special case. */

gcc/testsuite/ChangeLog

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2017-11-19 Paul Thomas <[email protected]>
2+
3+
PR fortran/78990
4+
* gfortran.dg/class_67.f90: New test.
5+
16
2017-11-19 Jan Hubicka <[email protected]>
27

38
PR target/82713
@@ -270,7 +275,7 @@
270275
* g++.dg/torture/pr82985.C: Likewise.
271276

272277
2017-11-15 Sebastian Peryt <[email protected]>
273-
278+
274279
PR target/82941
275280
PR target/82942
276281
* gcc.target/i386/pr82941-1.c: New test.

0 commit comments

Comments
 (0)