Skip to content

[flang] false warning for C pointer to noninteroperable derived-type #167470

@ivan-pi

Description

@ivan-pi

I am trying to compile the following snippet which makes a pointer round-trip with a non-interoperable entity:

program test
use, intrinsic :: iso_c_binding
implicit none

type :: foo
   integer :: b(3), c(2)
end type

type(foo), target :: x
type(foo), pointer :: p
type(c_ptr) :: pp

pp = c_loc(x)
call c_f_pointer(pp,p)

end program

This use case is important for interoperability, i.e. exposing Fortran classes and TPBs as opaque pointers in C. When applying -pedantic I see the warning:

/app/example.f90:14:21: portability: FPTR= argument to C_F_POINTER() should not have a derived type that is not BIND(C) [-Wportability]
  call c_f_pointer(pp,p)

I suspect this is a false positive; according to J3/24-007, pg 504, sec 18.2.3.3, the case above would fall under case (ii):

If the value of CPTR is the result of a reference to C_LOC with a noninteroperable effective argument X, FPTR shall be a nonpolymorphic pointer with the same type and type parameters as X. In this case, X shall not have been deallocated or have become undefined due to execution of a RETURN or END statement since the reference.

A little variation of this example would be to use a polymorphic pointer argument:

type(foo), target :: x
class(foo), pointer :: p
type(c_ptr) :: pp

pp = c_loc(x)
call c_f_pointer(pp,p) ! Error: p should not be polymorphic pointer

In this case, gfortran correctly reports:

   14 | call c_f_pointer(pp,p)
      |                    1
Error: FPTR argument at (1) to C_F_POINTER shall not be polymorphic

Obviously, the compiler needs to know the true dynamic type (size, layout, vtable) to make the association.

It would be of great value if flang could catch this class of errors.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions