[Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218 janus at gcc dot gnu.org changed: What|Removed |Added Target Milestone|--- |4.9.0
[Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218 Dominique d'Humieres dominiq at lps dot ens.fr changed: What|Removed |Added Status|NEW |RESOLVED CC||bur...@net-b.de Resolution|--- |FIXED --- Comment #5 from Dominique d'Humieres dominiq at lps dot ens.fr --- Seems to work fine on 4.10 (20140710). Confirmed for 4.10 and 4.9. Revision r199435 (2013-05-30) segfault, r199960 (2013-06-11) does not. The fix found be related to Tobias' work on finalization (pr37336, r199643 or r199851). Closing.
[Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218 --- Comment #4 from Rich Townsend townsend at astro dot wisc.edu --- Seems to work fine on 4.10 (20140710).
[Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218 janus at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2013-02-06 CC||janus at gcc dot gnu.org Summary|Segfault with allocatable |[OOP] Segfault with |intent(out) derived type|allocatable intent(out) |argument having allocatable |derived type argument |component |having allocatable ||component Ever Confirmed|0 |1 --- Comment #1 from janus at gcc dot gnu.org 2013-02-06 09:26:59 UTC --- Confirmed. I get a runtime segfault with 4.6, 4.7 and trunk (though with 4.6 it seems to be slightly different). Further reduced test case: program test_poly implicit none type :: foo_t real, allocatable :: a(:) end type class(foo_t), allocatable :: f call do_stuff(f) contains subroutine do_stuff (f) class(foo_t), intent(out), allocatable :: f end subroutine end program The dump shows the following: do_stuff (struct __class_test_poly_Foo_t_a restrict f) { if (f-_data-a.data != 0B) { __builtin_free ((void *) f-_data-a.data); } f-_data-a.data = 0B; } So the problem is clear: Before freeing the allocatable components, we do not check whether 'f-_data' is null (i.e. whether 'f' is allocated at all).
[Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218 --- Comment #2 from janus at gcc dot gnu.org 2013-02-06 10:08:59 UTC --- Here is a draft patch, which seems to fix the test case: Index: gcc/fortran/trans-decl.c === --- gcc/fortran/trans-decl.c(revision 195644) +++ gcc/fortran/trans-decl.c(working copy) @@ -3505,6 +3505,15 @@ init_intent_out_dt (gfc_symbol * proc_sym, gfc_wra present, tmp, build_empty_stmt (input_location)); } +else if (CLASS_DATA (f-sym)-attr.allocatable) + { +present = gfc_class_data_get (f-sym-backend_decl); +present = fold_build2_loc (input_location, NE_EXPR, +boolean_type_node, present, +fold_convert (TREE_TYPE (present), null_pointer_node)); +tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), + present, tmp, build_empty_stmt (input_location)); + } gfc_add_expr_to_block (init, tmp); } I think the same problem exists with TYPE(foo_t) instead of CLASS(foo_t), which is not yet handled by the patch. However I do not get a valgrind failure for the TYPE version for some reason. In fact, I'm not sure if we correctly pass the argument to 'do_stuff' for the TYPE version: struct foo_t * f; [...] f = 0B; do_stuff (f); If I'm not missing anything, I think we should pass 'f' directly instead of 'f': do_stuff (struct foo_t * restrict f) { if (f-a.data != 0B) { __builtin_free ((void *) f-a.data); } f-a.data = 0B; }
[Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218 --- Comment #3 from janus at gcc dot gnu.org 2013-02-06 10:16:29 UTC --- (In reply to comment #2) If I'm not missing anything, I think we should pass 'f' directly instead of 'f': do_stuff (struct foo_t * restrict f) { if (f-a.data != 0B) { __builtin_free ((void *) f-a.data); } f-a.data = 0B; } Or rather the generated code should read like this: if ((*f)-a.data != 0B) { __builtin_free ((void *) (*f)-a.data); } (*f)-a.data = 0B; Once we do this correctly, it should segfault as in the CLASS version, and we also need to add a check for (*f) != OB