Bug 45384 - [OOP] double free with SELECT TYPE
Summary: [OOP] double free with SELECT TYPE
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Daniel Kraft
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2010-08-23 14:43 UTC by Salvatore Filippone
Modified: 2010-08-26 19:52 UTC (History)
3 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2010-08-25 16:34:16


Attachments
test-case (373 bytes, text/plain)
2010-08-23 14:44 UTC, Salvatore Filippone
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Salvatore Filippone 2010-08-23 14:43:30 UTC
The attached and rather innocuous looking code generates the subject error.
It is a simplified version of a much more complex test case (in which the select type is entered within a loop and the error shows up at the second iteration) 
===========================================================================
[sfilippo@localhost bug20]$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/gnu46/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran
Thread model: posix
gcc version 4.6.0 20100823 (experimental) (GCC) 
[sfilippo@localhost bug20]$ gfortran -o bug20 bug20.f90
[sfilippo@localhost bug20]$ ./bug20 
 NV =           10
*** glibc detected *** ./bug20: double free or corruption (fasttop): 0x00000000018d8ae0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3381475676]
./bug20[0x400b53]
./bug20[0x400b91]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x338141ec5d]
./bug20[0x4007a9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:09 983344                             /home/sfilippo/NUMERICAL/NewPSBLAS/GNUbugs/bug20/bug20
00601000-00602000 rw-p 00001000 08:09 983344                             /home/sfilippo/NUMERICAL/NewPSBLAS/GNUbugs/bug20/bug20
018d8000-018f9000 rw-p 00000000 00:00 0                                  [heap]
3381000000-338101e000 r-xp 00000000 08:06 4964354                        /lib64/ld-2.12.so
338121e000-338121f000 r--p 0001e000 08:06 4964354                        /lib64/ld-2.12.so
338121f000-3381220000 rw-p 0001f000 08:06 4964354                        /lib64/ld-2.12.so
3381220000-3381221000 rw-p 00000000 00:00 0 
3381400000-3381575000 r-xp 00000000 08:06 4964358                        /lib64/libc-2.12.so
3381575000-3381775000 ---p 00175000 08:06 4964358                        /lib64/libc-2.12.so
3381775000-3381779000 r--p 00175000 08:06 4964358                        /lib64/libc-2.12.so
3381779000-338177a000 rw-p 00179000 08:06 4964358                        /lib64/libc-2.12.so
338177a000-338177f000 rw-p 00000000 00:00 0 
3381800000-3381883000 r-xp 00000000 08:06 4964404                        /lib64/libm-2.12.so
3381883000-3381a82000 ---p 00083000 08:06 4964404                        /lib64/libm-2.12.so
3381a82000-3381a83000 r--p 00082000 08:06 4964404                        /lib64/libm-2.12.so
3381a83000-3381a84000 rw-p 00083000 08:06 4964404                        /lib64/libm-2.12.so
3382c00000-3382cf1000 r-xp 00000000 08:06 5092887                        /usr/lib64/libgfortran.so.3.0.0
3382cf1000-3382ef1000 ---p 000f1000 08:06 5092887                        /usr/lib64/libgfortran.so.3.0.0
3382ef1000-3382ef3000 rw-p 000f1000 08:06 5092887                        /usr/lib64/libgfortran.so.3.0.0
3382ef3000-3382ef4000 rw-p 00000000 00:00 0 
3385000000-3385016000 r-xp 00000000 08:06 4964412                        /lib64/libgcc_s-4.4.4-20100630.so.1
3385016000-3385215000 ---p 00016000 08:06 4964412                        /lib64/libgcc_s-4.4.4-20100630.so.1
3385215000-3385216000 rw-p 00015000 08:06 4964412                        /lib64/libgcc_s-4.4.4-20100630.so.1
7f7a0b89c000-7f7a0b8a0000 rw-p 00000000 00:00 0 
7f7a0b8d0000-7f7a0b8d1000 rw-p 00000000 00:00 0 
7fffc443b000-7fffc4450000 rw-p 00000000 00:00 0                          [stack]
7fffc4563000-7fffc4564000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Abortito (core dumped)
Comment 1 Salvatore Filippone 2010-08-23 14:44:00 UTC
Created attachment 21548 [details]
test-case
Comment 2 Dominique d'Humieres 2010-08-23 14:58:55 UTC
Confirmed. Valgrind gives

==89074== Invalid free() / delete / delete[]
==89074==    at 0x10001079F: free (vg_replace_malloc.c:366)
==89074==    by 0x100000D15: MAIN__ (in ./a.out)
==89074==    by 0x100000D55: main (in ./a.out)
==89074==  Address 0x1003c9470 is 0 bytes inside a block of size 48 free'd
==89074==    at 0x10001079F: free (vg_replace_malloc.c:366)
==89074==    by 0x100000B6A: __d_mat_mod_MOD_doit (in ./a.out)
==89074==    by 0x100000D00: MAIN__ (in ./a.out)
==89074==    by 0x100000D55: main (in ./a.out)
Comment 3 janus 2010-08-23 15:36:11 UTC
Reduced test case:

program bug20

  type :: d_base_sparse_mat
    integer :: v(10) = 0.
  end type d_base_sparse_mat

  class(d_base_sparse_mat),allocatable :: a

  allocate (d_base_sparse_mat :: a)

  select type(aa => a)
  type is (d_base_sparse_mat)
    write(0,*) 'NV = ',size(aa%v)
  class default 
    write(0,*) 'Not implemented yet '
  end select

end program bug20


Note: The double free only happens when an associate-name is used.
Comment 4 Salvatore Filippone 2010-08-24 10:24:09 UTC
(In reply to comment #3)
With dump-tree-original I see this code snippet: 

        finally
          {
            if (aa.$data != 0B)
              {
                __builtin_free ((void *) aa.$data);
              }
          }

I believe this is wrong, because aa.$data is always an alias to an independently allocated data area, hence the double free. Of course I have no idea why this happens or how to fix it, but you already guessed that :-)
Comment 5 Salvatore Filippone 2010-08-24 12:50:24 UTC
(In reply to comment #3)
> Reduced test case:
> 
> program bug20
> 
>   type :: d_base_sparse_mat
>     integer :: v(10) = 0.
>   end type d_base_sparse_mat
> 
>   class(d_base_sparse_mat),allocatable :: a
> 
>   allocate (d_base_sparse_mat :: a)
> 
>   select type(aa => a)
>   type is (d_base_sparse_mat)
>     write(0,*) 'NV = ',size(aa%v)
>   class default 
>     write(0,*) 'Not implemented yet '
>   end select
> 
> end program bug20
> 
> 
> Note: The double free only happens when an associate-name is used.
> 
Changing the original example as follows: 
  subroutine doit(a)
    type(d_sparse_mat), intent(in) :: a
    integer :: i , nv
    call doselect(a%a)
  end subroutine doit

  subroutine doselect(aa)
    class(base_sparse_mat) :: aa
    select type(aa)
    type is (d_base_sparse_mat)
      nv = size(aa%v)
      write(0,*) 'NV = ',nv
    class default 
      write(0,*) 'Not implemented yet '
    end select
  end subroutine doselect

makes it work. 
However, when the same change is applied to the original library, a double free pops up in another place, unrelated to this issue; this would indicate that there are other instances of some sort of flaw in the cleanup of temporaries. 
Comment 6 janus 2010-08-24 12:57:38 UTC
(In reply to comment #5)
> However, when the same change is applied to the original library, a double free
> pops up in another place, unrelated to this issue; this would indicate that
> there are other instances of some sort of flaw in the cleanup of temporaries. 

Cf. PR 44047 (which is similar to this, except that the polymorphic selector itself is allocatable).
Comment 7 Salvatore Filippone 2010-08-24 13:05:59 UTC
(In reply to comment #6)

> 
> Cf. PR 44047 (which is similar to this, except that the polymorphic selector
> itself is allocatable).
> 
Yes, there indeed is a family air to this problem.....it's probably one and the same issue: correct cleanup of the temporary. From its description, I would expect a solution to fix bot PRs. 
Eagerly waiting for one such fix (to test against the full application....)
Comment 8 Daniel Kraft 2010-08-25 16:34:16 UTC
Taking.
Comment 9 Daniel Kraft 2010-08-26 19:49:31 UTC
Subject: Bug 45384

Author: domob
Date: Thu Aug 26 19:48:43 2010
New Revision: 163572

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163572
Log:
2010-08-26  Daniel Kraft  <d@domob.eu>

	PR fortran/38936
	PR fortran/44047
	PR fortran/45384
	* gfortran.h (struct gfc_association_list): New flag `dangling'.
	(gfc_build_block_ns): Declared here...
	* parse.h (gfc_build_block_ns): ...instead of here.
	* trans.h (gfc_process_block_locals): Expect additionally the
	gfc_association_list of BLOCK (if present).
	* match.c (select_type_set_tmp): Create sym->assoc for temporary.
	* resolve.c (resolve_variable): Only check for invalid *array*
	references on associate-names.
	(resolve_assoc_var): New method with code previously in resolve_symbol.
	(resolve_select_type): Use association to give the selector and
	temporaries their values instead of ordinary assignment.
	(resolve_fl_var_and_proc): Allow CLASS associate-names.
	(resolve_symbol): Use new `resolve_assoc_var' instead of inlining here.
	* trans-stmt.c (gfc_trans_block_construct): Pass association-list
	to `gfc_process_block_locals' to match new interface.
	* trans-decl.c (gfc_get_symbol_decl): Don't defer associate-names
	here automatically.
	(gfc_process_block_locals): Defer them rather here when linked to
	from the BLOCK's association list.

2010-08-26  Daniel Kraft  <d@domob.eu>

	PR fortran/38936
	PR fortran/44047
	PR fortran/45384
	* gfortran.dg/associate_8.f03: New test.
	* gfortran.dg/select_type_13.f03: New test.
	* gfortran.dg/select_type_14.f03: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/associate_8.f03
    trunk/gcc/testsuite/gfortran.dg/select_type_13.f03
    trunk/gcc/testsuite/gfortran.dg/select_type_14.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/match.c
    trunk/gcc/fortran/parse.h
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans.h
    trunk/gcc/testsuite/ChangeLog

Comment 10 Daniel Kraft 2010-08-26 19:52:51 UTC
Fixed.