aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorvehre <vehre@138bc75d-0d04-0410-961f-82ee72b054a4>2016-11-06 16:10:22 +0000
committervehre <vehre@138bc75d-0d04-0410-961f-82ee72b054a4>2016-11-06 16:10:22 +0000
commit5055cc9834c33b5a7b9ec57194454c9b558dbf25 (patch)
tree9ac441670f08e2dbbef73cdcca9444907c806f9e /gcc/fortran/resolve.c
parentddd81c4dc77e921fd7dbff2bba343bf031cddba0 (diff)
gcc/testsuite/ChangeLog:
2016-11-06 Andre Vehreschild <vehre@gcc.gnu.org> * gfortran.dg/allocate_with_source_14.f03: Fixed number mallocs occuring. gcc/fortran/ChangeLog: 2016-11-06 Andre Vehreschild <vehre@gcc.gnu.org> * expr.c (is_non_empty_structure_constructor): New function to detect non-empty structure constructor. (gfc_has_default_initializer): Analyse initializers. * resolve.c (cond_init): Removed. (resolve_allocate_expr): Removed dead code. Moved invariant code out of the loop over all objects to allocate. (resolve_allocate_deallocate): Added the invariant code remove from resolve_allocate_expr. * trans-array.c (gfc_array_allocate): Removed nullify of structure components in favour of doing this in gfc_trans_allocate for both scalars and arrays in the same place. * trans-expr.c (gfc_trans_init_assign): Always using _vptr->copy for class objects. * trans-stmt.c (allocate_get_initializer): Get the initializer expression for object allocated. (gfc_trans_allocate): Nullify a derived type only, when no SOURCE= or MOLD= is present preventing duplicate work. Moved the creation of the init-expression here to prevent code for conditions that can not occur on freshly allocated object, like checking for the need to free allocatable components. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241885 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c83
1 files changed, 20 insertions, 63 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 4e245cff5b2..9620ce67a0f 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -7048,35 +7048,6 @@ conformable_arrays (gfc_expr *e1, gfc_expr *e2)
return true;
}
-static void
-cond_init (gfc_code *code, gfc_expr *e, int pointer, gfc_expr *init_e)
-{
- gfc_code *block;
- gfc_expr *cond;
- gfc_code *init_st;
- gfc_expr *e_to_init = gfc_expr_to_initialize (e);
-
- cond = pointer
- ? gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_ASSOCIATED,
- "associated", code->loc, 2, gfc_copy_expr (e_to_init), NULL)
- : gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_ALLOCATED,
- "allocated", code->loc, 1, gfc_copy_expr (e_to_init));
-
- init_st = gfc_get_code (EXEC_INIT_ASSIGN);
- init_st->loc = code->loc;
- init_st->expr1 = e_to_init;
- init_st->expr2 = init_e;
-
- block = gfc_get_code (EXEC_IF);
- block->loc = code->loc;
- block->block = gfc_get_code (EXEC_IF);
- block->block->loc = code->loc;
- block->block->expr1 = cond;
- block->block->next = init_st;
- block->next = code->next;
-
- code->next = block;
-}
/* Resolve the expression in an ALLOCATE statement, doing the additional
checks to see whether the expression is OK or not. The expression must
@@ -7327,34 +7298,6 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
/* We have to zero initialize the integer variable. */
code->expr3 = gfc_get_int_expr (gfc_default_integer_kind, &e->where, 0);
}
- else if (!code->expr3)
- {
- /* Set up default initializer if needed. */
- gfc_typespec ts;
- gfc_expr *init_e;
-
- if (gfc_bt_struct (code->ext.alloc.ts.type))
- ts = code->ext.alloc.ts;
- else
- ts = e->ts;
-
- if (ts.type == BT_CLASS)
- ts = ts.u.derived->components->ts;
-
- if (gfc_bt_struct (ts.type) && (init_e = gfc_default_initializer (&ts)))
- cond_init (code, e, pointer, init_e);
- }
- else if (code->expr3->mold && code->expr3->ts.type == BT_DERIVED)
- {
- /* Default initialization via MOLD (non-polymorphic). */
- gfc_expr *rhs = gfc_default_initializer (&code->expr3->ts);
- if (rhs != NULL)
- {
- gfc_resolve_expr (rhs);
- gfc_free_expr (code->expr3);
- code->expr3 = rhs;
- }
- }
if (e->ts.type == BT_CLASS && !unlimited && !UNLIMITED_POLY (code->expr3))
{
@@ -7366,10 +7309,9 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
else if (code->ext.alloc.ts.type == BT_DERIVED)
ts = code->ext.alloc.ts;
+ /* Finding the vtab also publishes the type's symbol. Therefore this
+ statement is necessary. */
gfc_find_derived_vtab (ts.u.derived);
-
- if (dimension)
- e = gfc_expr_to_initialize (e);
}
else if (unlimited && !UNLIMITED_POLY (code->expr3))
{
@@ -7383,10 +7325,9 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
gcc_assert (ts);
+ /* Finding the vtab also publishes the type's symbol. Therefore this
+ statement is necessary. */
gfc_find_vtab (ts);
-
- if (dimension)
- e = gfc_expr_to_initialize (e);
}
if (dimension == 0 && codimension == 0)
@@ -7690,6 +7631,22 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
if (strcmp (fcn, "ALLOCATE") == 0)
{
bool arr_alloc_wo_spec = false;
+
+ /* Resolving the expr3 in the loop over all objects to allocate would
+ execute loop invariant code for each loop item. Therefore do it just
+ once here. */
+ if (code->expr3 && code->expr3->mold
+ && code->expr3->ts.type == BT_DERIVED)
+ {
+ /* Default initialization via MOLD (non-polymorphic). */
+ gfc_expr *rhs = gfc_default_initializer (&code->expr3->ts);
+ if (rhs != NULL)
+ {
+ gfc_resolve_expr (rhs);
+ gfc_free_expr (code->expr3);
+ code->expr3 = rhs;
+ }
+ }
for (a = code->ext.alloc.list; a; a = a->next)
resolve_allocate_expr (a->expr, code, &arr_alloc_wo_spec);