&& CLASS_DATA (sym)->attr.dimension == 0
&& sym->result == sym)
{
- tmp = CLASS_DATA (sym)->backend_decl;
- tmp = fold_build3_loc (input_location, COMPONENT_REF,
- TREE_TYPE (tmp), result, tmp, NULL_TREE);
- gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp),
- null_pointer_node));
+ tmp = gfc_class_data_get (result);
+ gfc_add_modify (&init, tmp,
+ fold_convert (TREE_TYPE (tmp),
+ null_pointer_node));
+ gfc_reset_vptr (&init, nullptr, result,
+ CLASS_DATA (sym->result)->ts.u.derived);
}
else if (sym->ts.type == BT_DERIVED
&& !sym->attr.allocatable)
return base_expr;
}
-
/* Reset the vptr to the declared type, e.g. after deallocation.
Use the variable in CLASS_CONTAINER if available. Otherwise, recreate
- one with E. The generated assignment code is added at the end of BLOCK. */
+ one with e or derived. At least one of the two has to be set. The generated
+ assignment code is added at the end of BLOCK. */
void
-gfc_reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_container)
+gfc_reset_vptr (stmtblock_t *block, gfc_expr *e, tree class_container,
+ gfc_symbol *derived)
{
tree vptr = NULL_TREE;
if (vptr == NULL_TREE)
{
gfc_se se;
+ gcc_assert (e);
/* Evaluate the expression and obtain the vptr from it. */
gfc_init_se (&se, NULL);
tree vtable;
/* Return the vptr to the address of the declared type. */
- vtab = gfc_find_derived_vtab (e->ts.u.derived);
+ vtab = gfc_find_derived_vtab (derived ? derived : e->ts.u.derived);
vtable = vtab->backend_decl;
if (vtable == NULL_TREE)
vtable = gfc_get_symbol_decl (vtab);
tree gfc_vptr_copy_get (tree);
tree gfc_vptr_final_get (tree);
tree gfc_vptr_deallocate_get (tree);
-void gfc_reset_vptr (stmtblock_t *, gfc_expr *, tree = NULL_TREE);
+void
+gfc_reset_vptr (stmtblock_t *, gfc_expr *, tree = NULL_TREE,
+ gfc_symbol * = nullptr);
void gfc_reset_len (stmtblock_t *, gfc_expr *);
tree gfc_get_class_from_gfc_expr (gfc_expr *);
tree gfc_get_class_from_expr (tree);
end function newContainer
end program returned_memory_leak
-! { dg-final { scan-tree-dump-times "newabstract" 14 "original" } }
+! { dg-final { scan-tree-dump-times "newabstract" 15 "original" } }
! { dg-final { scan-tree-dump-times "__builtin_free" 8 "original" } }
--- /dev/null
+! { dg-do run }
+!
+! PR fortran/90076
+!
+! Contributed by Brad Richardson <everythingfunctional@protonmail.com>
+!
+
+program assignment_memory_leak
+ implicit none
+
+ type, abstract :: base
+ end type base
+
+ type, extends(base) :: extended
+ end type extended
+
+ call run()
+contains
+ subroutine run()
+ class(base), allocatable :: var
+
+ var = newVar() ! Crash fixed
+ end subroutine run
+
+ function newVar()
+ class(extended), allocatable :: newVar
+ end function newVar
+end program assignment_memory_leak
+