Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Flang] Incorrect diagnostic on NULL(allocatable) as actual argument for generic resolution #125928

Open
DanielCChen opened this issue Feb 5, 2025 · 5 comments
Assignees

Comments

@DanielCChen
Copy link
Contributor

Consider the following code

module m
    type Base
        integer i
    end type

    type, extends(Base) :: Child
        integer j
    end type

    interface printMe
        subroutine printBase(b)
            import Base
            type(Base), pointer :: b
        end subroutine

        subroutine printChild(c)
            import Child
            type(Child), allocatable :: c
        end subroutine
    end interface printMe
end module

program generic002
use m
    type(Base), pointer :: b1
    type(Child), allocatable :: c1

    allocate(b1, SOURCE=Base(10))
    allocate(c1, SOURCE=Child(8, 9))

    call printMe(null(b1))
    call printMe(null(c1))
end

Flang currently issues an error as:

error: Semantic errors in t.f
./t.f:32:5: error: No specific subroutine of generic 'printme' matches the actual arguments
      call printMe(null(c1))
      ^^^^^^^^^^^^^^^^^^^^^^

The code seems valid as null(c1) should have a allocatable result of the same type as c1.

@llvmbot
Copy link
Member

llvmbot commented Feb 5, 2025

@llvm/issue-subscribers-flang-frontend

Author: Daniel Chen (DanielCChen)

Consider the following code ``` module m type Base integer i end type
type, extends(Base) :: Child
    integer j
end type

interface printMe
    subroutine printBase(b)
        import Base
        type(Base), pointer :: b
    end subroutine

    subroutine printChild(c)
        import Child
        type(Child), allocatable :: c
    end subroutine
end interface printMe

end module

program generic002
use m
type(Base), pointer :: b1
type(Child), allocatable :: c1

allocate(b1, SOURCE=Base(10))
allocate(c1, SOURCE=Child(8, 9))

call printMe(null(b1))
call printMe(null(c1))

end


Flang currently issues an error as:

error: Semantic errors in t.f
./t.f:32:5: error: No specific subroutine of generic 'printme' matches the actual arguments
call printMe(null(c1))
^^^^^^^^^^^^^^^^^^^^^^


The code seems valid as `null(c1)` should have a allocatable result of the same type as `c1`.
</details>

@akuhlens
Copy link
Contributor

akuhlens commented Feb 6, 2025

I think you may be correct that this is a bug. The reason your program is rejected doesn't really have to do with generics. To see why, I encourage you to look at the following example which should compile and run with Flang.

module m
    implicit none
    type Base
        integer i
    end type

    type, extends(Base) :: Child
        integer j
    end type

    interface printMe
        module procedure printBase, printChild
    end interface
    interface printInMe
        module procedure printBase, printInChild
    end interface
contains
    subroutine printBase(b)
      type(Base), pointer :: b
      print *, "Base"
    end subroutine
    subroutine printChild(c)
      type(Child), allocatable :: c
      print *, "Child"
    end subroutine
    subroutine printInChild(c)
      type(Child), allocatable, Intent(in):: c
      print *, "InChild" 
    end subroutine
end module

program generic002
use m
    implicit none
    type(Base), pointer :: b1
    type(Child), allocatable :: c1

    allocate(b1, SOURCE=Base(10))
    allocate(c1, SOURCE=Child(8, 9))

    call printMe(null(b1))
    ! Static Error 1: No specific procedure works.
    !call printMe(null(c1))
    call printBase(null(b1))
    ! Static Error 2: Passing null for and non-intent(in) allocatable.
    !call printChild(null(c1))
    call printInChild(null(c1))
    call printInMe(null(c1)) 
end

Error 1 which you identified indicates that no specific procedure (concrete instance of a generic procedure) applies in the resolution of this generic call. To see why the expected specific procedure doesn't apply we can just call the one we expected, printChild, with the same arguments.

Error 2 shows that the reason the specific procedure didn't apply. Flang rejects calls to null allocatables unless they are intent(in). I haven't found any grounds for this in the standard yet, which could actually be a bug, but I am going to have to dig in more or ask for help to figure that out. If Flang did accept this call your original program would have been accepted.

Calls to printInChild and printInMe do work because of the intent(in) on the allocatable parameter.

Thanks for the bug report! It was a lot of fun to dig into 🤓. I will ask around to see if anyone knows where the null restriction comes from and get back with you here.

@eugeneepshteyn
Copy link
Contributor

@DanielCChen , given what @akuhlens wrote above, isn't this issue a duplicate of #115984 ?

@DanielCChen
Copy link
Contributor Author

@akuhlens @eugeneepshteyn Thanks for the analysis! Right. It is very likely a dup to #115984. It is just that the error message is not the same, so I am not 100% sure. I am in discussion with @klausler about #115984 btw and hopefully that one will resolve this as well.

@eugeneepshteyn
Copy link
Contributor

Since Peter owns #115984 , assigning this issue to him as well.

klausler added a commit to klausler/llvm-project that referenced this issue Feb 25, 2025
…dummy

We presently allow a NULL() actual argument to associate with a non-optional
dummy allocatable argument only under INTENT(IN).  This is too strict, as
it precludes the case of a dummy argument with default intent.
Continue to require that the actual argument be definable under INTENT(OUT)
and INTENT(IN OUT), and (contra XLF) interpret NULL() as being an expression,
not a definable variable, even when it is given an allocatable MOLD.

Fixes llvm#115984.
Fixes llvm#125928.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants