-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Description
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 programThis 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 pointerIn 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.