Bug 105658 - Passing array component to unlimited polymorphic routine passes wrong slice
Summary: Passing array component to unlimited polymorphic routine passes wrong slice
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 12.0
: P4 normal
Target Milestone: 14.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2022-05-19 09:28 UTC by zed.three
Modified: 2024-03-06 21:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-02-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description zed.three 2022-05-19 09:28:10 UTC
The following program:

    program f
    implicit none
    
    type :: foo
        integer :: member1
        integer :: member2
    end type foo
    
    type(foo), dimension(3) :: thing = [foo(1, 2), foo(3, 4), foo(5, 6)]
    
    call print_poly(thing%member1)
    call print_int(thing%member1)
    
    contains
        subroutine print_poly(array)
            class(*), dimension(:), intent(in) :: array
    
            select type(array)
            type is (integer)
                print*, array
            end select
        end subroutine
    
        subroutine print_int(array)
            integer, dimension(:), intent(in) :: array
    
            print*, array
        end subroutine
    end program f

prints:

           1           2           3
           1           3           5

when we would expect:

           1           3           5
           1           3           5

Adding `-fcheck=all`, we get the warning "Fortran runtime warning: An array temporary was created" _only_ for the call to `print_int`.

Adding an extra set of parentheses to the `print_poly` call (`call print_poly((thing%member1))` gives the expected behaviour, I guess because it's forcing an array temporary?

This behaviour is present in 4.9.4 through to the trunk currently available on Compiler Explorer ((Compiler-Explorer-Build-gcc-7da9a089608b0ca09683332ce014fb6184842724-binutils-2.38) 13.0.0 20220518 (experimental))
Comment 1 GCC Commits 2024-02-20 19:50:36 UTC
The master branch has been updated by Harald Anlauf <anlauf@gcc.gnu.org>:

https://gcc.gnu.org/g:14ba8d5b87acd5f91ab8b8c02165a0fd53dcc2f2

commit r14-9086-g14ba8d5b87acd5f91ab8b8c02165a0fd53dcc2f2
Author: Peter Hill <peter.hill@york.ac.uk>
Date:   Tue Feb 20 20:42:53 2024 +0100

    Fortran: fix passing array component ref to polymorphic procedures
    
            PR fortran/105658
    
    gcc/fortran/ChangeLog:
    
            * trans-expr.cc (gfc_conv_intrinsic_to_class): When passing an
            array component reference of intrinsic type to a procedure
            with an unlimited polymorphic dummy argument, a temporary
            should be created.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/PR105658.f90: New test.
    
    Signed-off-by: Peter Hill <peter.hill@york.ac.uk>
Comment 2 anlauf 2024-02-20 19:57:14 UTC
Fixed on mainline for gcc-14 so far.
Comment 3 anlauf 2024-03-06 21:12:06 UTC
Backporting to 13-branch appears to depend on a backport of Paul's commit
r14-870-g6c95fe9bc05537, or part of it, plus maybe more.  Might be risky.

Setting target milestone to 14 and closing.

Thanks to Peter for the patch!