public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug fortran/56218] New: Segfault with allocatable intent(out) derived type argument having allocatable component
@ 2013-02-06  5:08 townsend at astro dot wisc.edu
  2013-02-06  9:27 ` [Bug fortran/56218] [OOP] " janus at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: townsend at astro dot wisc.edu @ 2013-02-06  5:08 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56218

             Bug #: 56218
           Summary: Segfault with allocatable intent(out) derived type
                    argument having allocatable component
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: townsend@astro.wisc.edu


When using a subroutine with an allocatable intent(out) argument which is a
derived type, and this derived type itself contains an allocatable argument, a
segfault occurs on subroutine entry. The segfault disappears if the argument is
declared intent(inout).

Example code (compiled with gfortran 4.8.0 20121215 on OS X 10.7.5):

--
program test_poly

  implicit none

  type :: foo_t
     real, allocatable :: a(:)
  end type foo_t

  class(foo_t), allocatable :: f

  call do_stuff(f)

contains

  subroutine do_stuff (f)

    class(foo_t), intent(out), allocatable :: f

    allocate(f)

    allocate(f%a(3))

    f%a = [1.,2.,3.]

  end subroutine do_stuff

end program test_poly
--

Output from gdb:

--
(gdb) run
Starting program: /Users/townsend/test_poly 
Reading symbols for shared libraries ++++........................ done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00000001000015dd in do_stuff (f=Invalid F77 type code 3 in symbol table.
) at test_poly.f90:15
15      subroutine do_stuff (f)
(gdb) 
--


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
  2013-02-06  5:08 [Bug fortran/56218] New: Segfault with allocatable intent(out) derived type argument having allocatable component townsend at astro dot wisc.edu
@ 2013-02-06  9:27 ` janus at gcc dot gnu.org
  2013-02-06 10:09 ` janus at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: janus at gcc dot gnu.org @ 2013-02-06  9:27 UTC (permalink / raw)
  To: gcc-bugs


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).


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
  2013-02-06  5:08 [Bug fortran/56218] New: Segfault with allocatable intent(out) derived type argument having allocatable component townsend at astro dot wisc.edu
  2013-02-06  9:27 ` [Bug fortran/56218] [OOP] " janus at gcc dot gnu.org
@ 2013-02-06 10:09 ` janus at gcc dot gnu.org
  2013-02-06 10:17 ` janus at gcc dot gnu.org
  2014-07-15 19:40 ` dominiq at lps dot ens.fr
  3 siblings, 0 replies; 5+ messages in thread
From: janus at gcc dot gnu.org @ 2013-02-06 10:09 UTC (permalink / raw)
  To: gcc-bugs


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;
}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
  2013-02-06  5:08 [Bug fortran/56218] New: Segfault with allocatable intent(out) derived type argument having allocatable component townsend at astro dot wisc.edu
  2013-02-06  9:27 ` [Bug fortran/56218] [OOP] " janus at gcc dot gnu.org
  2013-02-06 10:09 ` janus at gcc dot gnu.org
@ 2013-02-06 10:17 ` janus at gcc dot gnu.org
  2014-07-15 19:40 ` dominiq at lps dot ens.fr
  3 siblings, 0 replies; 5+ messages in thread
From: janus at gcc dot gnu.org @ 2013-02-06 10:17 UTC (permalink / raw)
  To: gcc-bugs


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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug fortran/56218] [OOP] Segfault with allocatable intent(out) derived type argument having allocatable component
  2013-02-06  5:08 [Bug fortran/56218] New: Segfault with allocatable intent(out) derived type argument having allocatable component townsend at astro dot wisc.edu
                   ` (2 preceding siblings ...)
  2013-02-06 10:17 ` janus at gcc dot gnu.org
@ 2014-07-15 19:40 ` dominiq at lps dot ens.fr
  3 siblings, 0 replies; 5+ messages in thread
From: dominiq at lps dot ens.fr @ 2014-07-15 19:40 UTC (permalink / raw)
  To: gcc-bugs

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|                            |burnus@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.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-07-15 19:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-06  5:08 [Bug fortran/56218] New: Segfault with allocatable intent(out) derived type argument having allocatable component townsend at astro dot wisc.edu
2013-02-06  9:27 ` [Bug fortran/56218] [OOP] " janus at gcc dot gnu.org
2013-02-06 10:09 ` janus at gcc dot gnu.org
2013-02-06 10:17 ` janus at gcc dot gnu.org
2014-07-15 19:40 ` dominiq at lps dot ens.fr

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).