public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures
@ 2020-12-23 22:18 guez at lmd dot ens.fr
  2020-12-23 22:43 ` [Bug fortran/98433] " kargl at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: guez at lmd dot ens.fr @ 2020-12-23 22:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

            Bug ID: 98433
           Summary: double free detected in tcache 2, after merge of
                    structures
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: guez at lmd dot ens.fr
  Target Milestone: ---

This is the output of `gcc -v` on my machine:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
9.3.0-17ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs
--enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr
--with-gcc-major-version-only --program-suffix=-9
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug
--enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new
--enable-gnu-unique-object --disable-vtable-verify --enable-plugin
--enable-default-pie --with-system-zlib --with-target-system-zlib=auto
--enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686
--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic
--enable-offload-targets=nvptx-none=/build/gcc-9-HskZEa/gcc-9-9.3.0/debian/tmp-nvptx/usr,hsa
--without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

Here is a test program for the bug:

$ cat test_bug_merge.f90
module bug_merge_m
  implicit none
contains
  subroutine bug_merge
    type t
       real, allocatable:: v(:)
    end type t

    type(t) x1, x2, x3

    allocate(x1%v(1))
    x1%v = 1.
    allocate(x2%v(1))
    x2%v = 2.
    x3 = merge(x1, x2, .false.)
    print *, "x3%v = ", x3%v
  end subroutine bug_merge
end module bug_merge_m

program test_bug_merge
  use bug_merge_m, only: bug_merge
  implicit none
  call bug_merge
end program test_bug_merge

And here is the result of compilation and execution:

$ gfortran test_bug_merge.f90

$ a.out
 x3%v =    2.00000000    
free(): double free detected in tcache 2

Program received signal SIGABRT: Process abort signal.

Backtrace for this error:
#0  0x146659050d3a
#1  0x14665904fed5
#2  0x146658e7e20f
#3  0x146658e7e18b
#4  0x146658e5d858
#5  0x146658ec83ed
#6  0x146658ed047b
#7  0x146658ed20ec
#8  0x55a871b8756c
#9  0x55a871b8759c
#10  0x55a871b875d5
#11  0x146658e5f0b2
#12  0x55a871b8711d
#13  0xffffffffffffffff
Aborted (core dumped)

I think there is nothing wrong in the program. x1 and x2 are well defined. The
error disappears if I replace the merge line with a simple x3 = x2. The error
also disappears if I inline the content of the subroutine in the main program
unit. Also, the program works with the Intel compiler.

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
@ 2020-12-23 22:43 ` kargl at gcc dot gnu.org
  2020-12-23 23:29 ` guez at lmd dot ens.fr
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-12-23 22:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

kargl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargl at gcc dot gnu.org
           Priority|P3                          |P4

--- Comment #1 from kargl at gcc dot gnu.org ---

The issue goes away if you replace this line:

x3 = merge(x1, x2, .false.)

with the likely correct line

x3%v = merge(x1%v, x2%v, .false.)

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
  2020-12-23 22:43 ` [Bug fortran/98433] " kargl at gcc dot gnu.org
@ 2020-12-23 23:29 ` guez at lmd dot ens.fr
  2020-12-24  0:52 ` sgk at troutmask dot apl.washington.edu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: guez at lmd dot ens.fr @ 2020-12-23 23:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

--- Comment #2 from Lionel GUEZ <guez at lmd dot ens.fr> ---
Sure, the issue goes away if you specify the components.

When you say "the likely correct line", do you imply that the line without the
components is incorrect? I would insist that the line without the components is
correct. See for example Adams, Fortran 2003 Handbook, 2009, section 7.5.2:
"Derived-type intrinsic assignment is performed as if the assignment were
expanded, component-by-component with corresponding elements from the variable
and the expression, into separate assignment statements. [...] If the component
is allocatable:
a. if it is allocated, it is deallocated.
b. if the corresponding component of the expression is allocated, the variable
component is allocated with the same dynamic type and type parameters and,
if it is an array, with the same bounds. [...]"

gfortran usually implements this well, as we can see when we replace the merge
with a simple x3 = x2. But there is something wrong here in gfortran when it
encounters the combination of derived-type assignment, merge function, and
being in a subroutine.

Since the line without the components is valid, the crash is a bug. (I might
add that, of course, I produced the simplest possible test case but, in my
original program, the allocatable component in the derived type is only one of
several components and so, it is not an equivalently satisfying code to
manually assign all components one by one.)

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
  2020-12-23 22:43 ` [Bug fortran/98433] " kargl at gcc dot gnu.org
  2020-12-23 23:29 ` guez at lmd dot ens.fr
@ 2020-12-24  0:52 ` sgk at troutmask dot apl.washington.edu
  2020-12-24  7:55 ` guez at lmd dot ens.fr
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: sgk at troutmask dot apl.washington.edu @ 2020-12-24  0:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

--- Comment #3 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Wed, Dec 23, 2020 at 11:29:47PM +0000, guez at lmd dot ens.fr wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433
> 
> --- Comment #2 from Lionel GUEZ <guez at lmd dot ens.fr> ---
> Sure, the issue goes away if you specify the components.
> 
> When you say "the likely correct line", do you imply that the line without the
> components is incorrect?

Likely, as in I need to check the Fortran standard for
the correct behavior.

> I would insist that the line without the components is
> correct. See for example Adams, Fortran 2003 Handbook, 2009, section 7.5.2:

Don't own that book.  In fact, I own no books that cover 
anything beyond Fortran 95.

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
                   ` (2 preceding siblings ...)
  2020-12-24  0:52 ` sgk at troutmask dot apl.washington.edu
@ 2020-12-24  7:55 ` guez at lmd dot ens.fr
  2020-12-24 12:01 ` anlauf at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: guez at lmd dot ens.fr @ 2020-12-24  7:55 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

--- Comment #4 from Lionel GUEZ <guez at lmd dot ens.fr> ---
Well, you will find that assignment of an expression of derived type to a
variable of the same type was already available in Fortran 95 (for example
Metcalf, 1999, Fortran 90/95 explained, section 3.9). But allocatable
components appeared in Fortran 2003. (I think it is time now we stopped
referring to Fortran 95.)

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
                   ` (3 preceding siblings ...)
  2020-12-24  7:55 ` guez at lmd dot ens.fr
@ 2020-12-24 12:01 ` anlauf at gcc dot gnu.org
  2020-12-24 19:31 ` kargl at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: anlauf at gcc dot gnu.org @ 2020-12-24 12:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
                 CC|                            |anlauf at gcc dot gnu.org
   Last reconfirmed|                            |2020-12-24
     Ever confirmed|0                           |1

--- Comment #5 from anlauf at gcc dot gnu.org ---
The user code is alright, it is the implementation of the intrinsic MERGE which
prevents doing the right thing when assigning to the l.h.s.

Extending the subroutine of the test program to

module bug_merge_m
  implicit none
contains
  subroutine bug_merge
    type t
       real, allocatable :: v(:)
    end type t

    type(t) :: x1, x2, x3, x4, x5
    logical :: f = .false.

    allocate(x1%v(1))
    x1%v = 1.
    allocate(x2%v(1))
    x2%v = 2.
    x3 = merge(x1, x2, .false.)
    print *, "x3%v = ", x3%v
    x4 = merge(x1, x2, f)
    print *, "x4%v = ", x4%v
    if (f) then; x5 = x1; else; x5 = x2; endif
    print *, "x5%v = ", x5%v
  end subroutine bug_merge
end module bug_merge_m

and looking a the generated dump-tree, one sees that the assignments to x3 and
x4 are generating wrong code, only the assignment to x5 is fine.

@Steve: that's pretty basic F2003 stuff, almost TR15581...

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
                   ` (4 preceding siblings ...)
  2020-12-24 12:01 ` anlauf at gcc dot gnu.org
@ 2020-12-24 19:31 ` kargl at gcc dot gnu.org
  2020-12-24 23:03 ` guez at lmd dot ens.fr
  2023-07-23 19:12 ` anlauf at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: kargl at gcc dot gnu.org @ 2020-12-24 19:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

--- Comment #6 from kargl at gcc dot gnu.org ---

> @Steve: that's pretty basic F2003 stuff, almost TR15581...

Yes, I know.  Point being that quoting some third-party 
interpretation of what one version of the Fortran standard
says is of limited value.  gfortran has -std=f95 etc.
Whatever the fix[*] is, it needs to work under the conditions
that a user may use -std=.

[*] I have a 3 line workaround that likely is a fix, but
am currently disinclined to submit it here.

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
                   ` (5 preceding siblings ...)
  2020-12-24 19:31 ` kargl at gcc dot gnu.org
@ 2020-12-24 23:03 ` guez at lmd dot ens.fr
  2023-07-23 19:12 ` anlauf at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: guez at lmd dot ens.fr @ 2020-12-24 23:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

--- Comment #7 from Lionel GUEZ <guez at lmd dot ens.fr> ---
(In reply to kargl from comment #6)

> Point being that quoting some third-party 
> interpretation of what one version of the Fortran standard
> says is of limited value.

OK. I am learning here. I thought those well-known books were considered as
authoritative. So in a discussion about what is valid or not, you would
consider really useful only a quote from the official Fortran standard?

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

* [Bug fortran/98433] double free detected in tcache 2, after merge of structures
  2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
                   ` (6 preceding siblings ...)
  2020-12-24 23:03 ` guez at lmd dot ens.fr
@ 2023-07-23 19:12 ` anlauf at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: anlauf at gcc dot gnu.org @ 2023-07-23 19:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98433

anlauf at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code

--- Comment #8 from anlauf at gcc dot gnu.org ---
We are now generating a shallow copy instead of a deep copy for the line:

    x3 = merge(x1, x2, .false.)

This gives:

      {
        struct t D.4345;
        struct t D.4346;
        struct t D.4347;

        D.4345 = x1;
        D.4346 = x2;
        D.4347 = x3;
        x3 = D.4346;
        if ((real(kind=4)[0:] * restrict) D.4347.v.data != 0B)
          {
            __builtin_free ((void *) D.4347.v.data);
            (real(kind=4)[0:] * restrict) D.4347.v.data = 0B;
          }
      }

while e.g. the assignment x3 = x2 produces:

...
        x3 = x2;
        if ((void *) x2.v.data != 0B)
          {
            D.4346 = (x2.v.dim[0].ubound - x2.v.dim[0].lbound) + 1;
            D.4347 = NON_LVALUE_EXPR <D.4346>;
            D.4348 = (void * restrict) __builtin_malloc (MAX_EXPR <(unsigned
long) (D.4347 * 4), 1>);
            x3.v.data = D.4348;
            __builtin_memcpy ((real(kind=4)[0:] * restrict) x3.v.data,
(real(kind=4)[0:] * restrict) x2.v.data, (unsigned long) (D.4347 * 4));
          }
        else
          {
            x3.v.data = 0B;
          }
...

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

end of thread, other threads:[~2023-07-23 19:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-23 22:18 [Bug fortran/98433] New: double free detected in tcache 2, after merge of structures guez at lmd dot ens.fr
2020-12-23 22:43 ` [Bug fortran/98433] " kargl at gcc dot gnu.org
2020-12-23 23:29 ` guez at lmd dot ens.fr
2020-12-24  0:52 ` sgk at troutmask dot apl.washington.edu
2020-12-24  7:55 ` guez at lmd dot ens.fr
2020-12-24 12:01 ` anlauf at gcc dot gnu.org
2020-12-24 19:31 ` kargl at gcc dot gnu.org
2020-12-24 23:03 ` guez at lmd dot ens.fr
2023-07-23 19:12 ` anlauf at gcc dot gnu.org

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