[Bug fortran/82996] ICE and segfault with derived type finalization

2023-03-18 Thread pault at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

Paul Thomas  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||pault at gcc dot gnu.org
 Resolution|--- |FIXED

--- Comment #12 from Paul Thomas  ---
Fixed on mainline. The testcases now have the same behaviour as ifort and
nagfor.

I will ask to backport to 12-branch in a few weeks.

Cheers

Paul

[Bug fortran/82996] ICE and segfault with derived type finalization

2023-03-18 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #11 from CVS Commits  ---
The master branch has been updated by Paul Thomas :

https://gcc.gnu.org/g:d7caf313525a46f200d7f5db1ba893f853774aee

commit r13-6747-gd7caf313525a46f200d7f5db1ba893f853774aee
Author: Paul Thomas 
Date:   Sat Mar 18 07:56:23 2023 +

Fortran: Fix bugs and missing features in finalization [PR37336]

2023-03-18  Paul Thomas  

gcc/fortran
PR fortran/103854
PR fortran/96122
PR fortran/37336
* class.cc (finalize_component): Include the missing arguments
in the call to the component's finalizer wrapper.
(has_finalizer_component): Do not return true for procedure
pointer components.
(finalizer_insert_packed_call): Remove the redundant argument
in the call to the final subroutine.
(generate_finalization_wrapper): Add support for assumed rank
finalizers.
(gfc_may_be_finalized): New helper function.
* dump-parse-tree.cc (write_proc): Whitespace.
* gfortran.h : Add prototype for gfc_may_be_finalized.
* resolve.cc (resolve_function): Correct derived types that
have an incomplete namespace.
(resolve_where, gfc_resolve_where_code_in_forall,
gfc_resolve_forall_body, gfc_resolve_code): Check that the op
code is still EXEC_ASSIGN. If it is set lhs to must finalize.
(is_finalizable_type): New function.
(generate_component_assignments): Set must_finalize if needed.
(gfc_resolve_finalizers): Error if assumed rank finalizer is
not the only one. Warning on lack of scalar finalizer modified
to account for assumed rank finalizers.
(generate_final_call): New function.
(generate_component_assignments): Enclose the outermost call in
a block to capture automatic deallocation and final calls.
Set must_finalize as required to satisfy the standards. Use an
explicit pointer assignment for pointer components to capture
finalization of the target. Likewise use explicit assignment
for allocatable components. Do not use the temporary copy of
the lhs in defined assignment if the component is allocatable.
Put the temporary in the same namespace as the lhs symbol if
the component may be finalized. Remove the leading assignment
from the expansion of assignment of components that have their
own defined assignment components. Suppress finalization of
assignment of temporary components to the lhs. Make an explicit
final call for the rhs function temporary if it exists.
(gfc_resolve_code): Set must_finalize for assignments with an
array constructor on the rhs.
(gfc_resolve_finalizers): Ensure that an assumed rank finalizer
is the only finalizer for that type and correct the surprising
warning for the lack of a scalar finalizer.
(check_defined_assignments): Handle allocatable components.
(resolve_fl_derived): Set referenced the vtab for use
associated symbols.
(resolve_symbol): Set referenced an unreferenced symbol that
will be finalized.
* trans-array.cc (gfc_trans_array_constructor_value): Add code
to finalize the constructor result. Warn that this feature was
removed in F2018 and that it is suppressed by -std=2018.
(trans_array_constructor): Add finalblock, pass to previous
and apply to loop->post if filled.
(gfc_add_loop_ss_code): Add se finalblock to outer loop post.
(gfc_trans_array_cobounds, gfc_trans_array_bounds): Add any
generated finalization code to the main block.
(structure_alloc_comps): Add boolean argument to suppress
finalization and use it for calls from
gfc_deallocate_alloc_comp_no_caf. Otherwise it defaults to
false.
(gfc_copy_alloc_comp_no_fini): New wrapper for
structure_alloc_comps.
(gfc_alloc_allocatable_for_assignment): Suppress finalization
by setting new arg in call to gfc_deallocate_alloc_comp_no_caf.
(gfc_trans_deferred_array): Use gfc_may_be_finalized and do not
deallocate the components of entities with a leading '_' in the
name that are also marked as artificial.
* trans-array.h : Add the new boolean argument to the prototype
of gfc_deallocate_alloc_comp_no_caf with a default of false.
Add prototype for gfc_copy_alloc_comp_no_fini.
* trans-decl.cc(init_intent_out_dt): Tidy up the code.
* trans-expr.cc (gfc_init_se): Initialize finalblock.

[Bug fortran/82996] ICE and segfault with derived type finalization

2018-09-28 Thread neil.n.carlson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #10 from Neil Carlson  ---
A reader on c.l.f suggested this workaround for the bug. I'm sharing it here
because I think it may help to isolate where the problem is.  The suggestion
was to make the B array component allocatable and allocate it inside SUB. This
allows more control over when its finalizer is called. Here's a modified
version the runs without error (with -fsanitize=address,undefined) and valgrind
shows nothing amiss. (I'm using the 9.0 trunk)

module mod

  type foo
integer, pointer :: f(:) => null()
  contains
final :: foo_destroy
  end type

  type bar
type(foo), allocatable :: b(:)
  end type

contains

  elemental subroutine foo_destroy(this)
type(foo), intent(inout) :: this
if (associated(this%f)) deallocate(this%f)
  end subroutine

end module

program main

  use mod
  type(bar) :: x
  call sub(x) ! x%b not allocated
  call sub(x) ! x%b is allocated

contains

  subroutine sub(x)
type(bar), intent(out) :: x
allocate(x%b(2))
  end subroutine

end program

The interesting thing is that the finalizer works just fine when the %B
component is allocatable and allocated (the second call to SUB), but not when
it is not allocatable.

[Bug fortran/82996] ICE and segfault with derived type finalization

2018-02-17 Thread neil.n.carlson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #9 from Neil Carlson  ---
With today's version (r257782) I'm still seeing the same thing Dominique
reported in comment 7, except that there is no longer any abort -- the programs
terminate successfully (0 exit code) despite the reported runtime error.  I'm
not sure what to make of that.

Example error:

 $ ./a.out
gfortran-20171114a.f90:48: runtime error: member access within misaligned
address 0x0060ab25 for type 'struct foo', which requires 8 byte alignment
0x0060ab25: note: pointer points here
 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00
00 00 00 00 00 00  00
 ^

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-16 Thread neil.n.carlson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #8 from neil.n.carlson at gmail dot com ---
> If I remove 'elemental' for 'subroutine foo_destroy', the segfault is gone.

In that case the final procedure doesn't match the array component and wouldn't
be called.  I suspect that is why the segfault is gone.

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-16 Thread dominiq at lps dot ens.fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

Dominique d'Humieres  changed:

   What|Removed |Added

 Blocks||37336

--- Comment #7 from Dominique d'Humieres  ---
> I think Dominique swapped 2 and 3.

Indeed!

If I compile the tests in comment 0 or 1 with '-fsanitize=address,undefined', I
get at run time an error of the kind:

pr82996.f90:17: runtime error: member access within misaligned address
0x1000e3e7620c for type 'struct foo', which requires 8 byte alignment
0x1000e47d2bec: note: pointer points here
ASAN:DEADLYSIGNAL
=
==3427==ERROR: AddressSanitizer: SEGV on unknown address 0x12001c8fa57d (pc
0x00010796507b bp 0x7ffee84cd9c0 sp 0x7ffee84cd150 T0)
#0 0x10796507a in wrap_write.part.20
(/opt/gcc/gcc7wr/lib/libasan.4.dylib+0x2507a)
#1 0x109224d2e in __sanitizer::IsAccessibleMemoryRange(unsigned long,
unsigned long) (/opt/gcc/gcc7wr/lib/libubsan.0.dylib+0x17d2e)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/opt/gcc/gcc7wr/lib/libasan.4.dylib+0x2507a)
in wrap_write.part.20
==3427==ABORTING

Program received signal SIGABRT: Process abort signal.


If I remove 'elemental' for 'subroutine foo_destroy', the segfault is gone.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37336
[Bug 37336] [F03] Finish derived-type finalization

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-16 Thread ondrej.certik at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

Ondřej Čertík  changed:

   What|Removed |Added

 CC||ondrej.certik at gmail dot com

--- Comment #6 from Ondřej Čertík  ---
The finalizers are the most serious problem with gfortran for us. Every other
bug we can workaround one way or another it seems, but the finalizers are very
hard to workaround, one essentially has to comment them out, not just in our
code, but also in all dependencies, and even then that introduces memory leaks.

What exactly is the problem? Is this a bug in the gfortran frontend, or
something more fundamental? Is this a relatively simple fix for somebody who
understands the internals, or would this require a significant time investment
and redesign of the code?

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-15 Thread neil.n.carlson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #5 from neil.n.carlson at gmail dot com ---
I've built the svn trunk and tested the examples with it.  The ICEs with the
comment 2 and 3 examples are gone, as Dominique found.  The comment 1 example
continues to segfault when executed, as does the comment 2 example now.  The
comment 3 example executes without error.  I think Dominique swapped 2 and 3.

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-15 Thread dominiq at lps dot ens.fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #4 from Dominique d'Humieres  ---
I see the problems on all gfortran supporting finalization (4.9 up to trunk
8.0), except the ICEs that are no longer present on recent trunk. The change
occurred between revisions r247817 (2017-05-09, ICE) and r248367 (2017-05-23,
compiles). In top of that the code in comment 2 executes without segfault.

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-14 Thread marxin at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

Martin Liška  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2017-11-15
 CC||marxin at gcc dot gnu.org
 Ever confirmed|0   |1

--- Comment #3 from Martin Liška  ---
Confirmed.

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-14 Thread neil.n.carlson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #2 from neil.n.carlson at gmail dot com ---
In the final example I drop the elemental attribute from the FOO final
procedure and modify the BAR final procedure to loop over the elements of its B
array component.  This too yields an ICE:

f951: internal compiler error: in generate_finalization_wrapper, at
fortran/class.c:1975

module mod

  type foo
integer, pointer :: f(:) => null()
  contains
final :: foo_destroy
  end type

  type bar
type(foo) :: b(2)
  contains
final :: bar_destroy
  end type

contains

  subroutine foo_destroy(this)
type(foo), intent(inout) :: this
if (associated(this%f)) deallocate(this%f)
  end subroutine

  subroutine bar_destroy(this)
type(bar), intent(inout) :: this
integer :: j
do j = 1, size(this%b)
  call foo_destroy(this%b(j))
end do
  end subroutine

end module

program main
  use mod
  type(bar) :: x
  call sub(x)
contains
  subroutine sub(x)
type(bar), intent(out) :: x
  end subroutine
end program

[Bug fortran/82996] ICE and segfault with derived type finalization

2017-11-14 Thread neil.n.carlson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82996

--- Comment #1 from neil.n.carlson at gmail dot com ---
In the second example, I add a final procedure for BAR (not necessary) and
explicitly call the FOO final procedure on its B component.  This gives an ICE

f951: internal compiler error: in generate_finalization_wrapper, at
fortran/class.c:1975

module mod

  type foo
integer, pointer :: f(:) => null()
  contains
final :: foo_destroy
  end type

  type bar
type(foo) :: b(2)
  contains
final :: bar_destroy
  end type

contains

  elemental subroutine foo_destroy(this)
type(foo), intent(inout) :: this
if (associated(this%f)) deallocate(this%f)
  end subroutine

  subroutine bar_destroy(this)
type(bar), intent(inout) :: this
call foo_destroy(this%b)
  end subroutine

end module

program main
  use mod
  type(bar) :: x
  call sub(x)
contains
  subroutine sub(x)
type(bar), intent(out) :: x
  end subroutine
end program