Peter Klausler cbe3b72c4c
[flang][CUDA] Downgrade error to warning (#161570)
The compiler currently emit an error about the lack of an explicit
procedure interface when an external procedure that is called via an
implicit interface is known to have an dummy argument with a CUDA data
attribute, even when the corresponding actual argument does have a CUDA
data attribute. This behavior is inconsistent with what happens when
such a call is to an external in another source file and its definition
is not visible -- the compiler silently accepts an actual argument with
a CUDA data attribute across the implicit interface.

Harmonize this situation so that an actual argument with a CUDA data
attribute in a reference to a procedure with an implicit interface
elicits a usage warning encouraging the use of explicit interfaces. Only
when the procedure's definition is visible, and incompatible, will an
error message appear.
2025-10-03 10:48:13 -07:00

170 lines
6.1 KiB
Fortran

! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
! NULL() intrinsic function error tests
subroutine test
interface
subroutine s0
end subroutine
subroutine s1(j)
integer, intent(in) :: j
end subroutine
subroutine canbenull(x, y)
integer, intent(in), optional :: x
real, intent(in), pointer :: y
end
subroutine optionalAllocatable(x)
integer, intent(in), allocatable, optional :: x
end
function f0()
real :: f0
end function
function f1(x)
real :: f1
real, intent(inout) :: x
end function
function f2(p)
import s0
real :: f1
procedure(s0), pointer, intent(inout) :: p
end function
function f3()
import s1
procedure(s1), pointer :: f3
end function
end interface
external implicit
type :: dt0
integer, pointer :: ip0
integer :: n = 666
end type dt0
type :: dt1
integer, pointer :: ip1(:)
end type dt1
type :: dt2
procedure(s0), pointer, nopass :: pps0
end type dt2
type :: dt3
procedure(s1), pointer, nopass :: pps1
end type dt3
type :: dt4
real, allocatable :: ra0
end type dt4
type, extends(dt4) :: dt5
end type dt5
integer :: j
type(dt0) :: dt0x
type(dt1) :: dt1x
type(dt2) :: dt2x
type(dt3) :: dt3x
type(dt4) :: dt4x
integer, pointer :: ip0, ip1(:), ip2(:,:)
integer, allocatable :: ia0, ia1(:), ia2(:,:)
real, pointer :: rp0, rp1(:)
integer, parameter :: ip0r = rank(null(mold=ip0))
integer, parameter :: ip1r = rank(null(mold=ip1))
integer, parameter :: ip2r = rank(null(mold=ip2))
integer, parameter :: eight = ip0r + ip1r + ip2r + 5
real(kind=eight) :: r8check
logical, pointer :: lp
type(dt4), pointer :: dt4p
type(dt5), pointer :: dt5p
ip0 => null() ! ok
ip0 => null(null()) ! ok
ip0 => null(null(null())) ! ok
ip1 => null() ! ok
ip1 => null(null()) ! ok
ip1 => null(null(null())) ! ok
ip2 => null() ! ok
ip2 => null(null()) ! ok
ip2 => null(null(null())) ! ok
!ERROR: MOLD= argument to NULL() must be a pointer or allocatable
ip0 => null(mold=1)
!ERROR: MOLD= argument to NULL() must be a pointer or allocatable
ip0 => null(null(mold=1))
!ERROR: MOLD= argument to NULL() must be a pointer or allocatable
ip0 => null(mold=j)
!ERROR: MOLD= argument to NULL() must be a pointer or allocatable
ip0 => null(mold=null(mold=j))
dt0x = dt0(null())
dt0x = dt0(ip0=null())
dt0x = dt0(ip0=null(ip0))
dt0x = dt0(ip0=null(mold=ip0))
!ERROR: function result type 'REAL(4)' is not compatible with pointer type 'INTEGER(4)'
dt0x = dt0(ip0=null(mold=rp0))
!ERROR: A NULL pointer may not be used as the value for component 'n'
dt0x = dt0(null(), null())
!ERROR: function result type 'REAL(4)' is not compatible with pointer type 'INTEGER(4)'
dt1x = dt1(ip1=null(mold=rp1))
dt2x = dt2(pps0=null())
dt2x = dt2(pps0=null(mold=dt2x%pps0))
!ERROR: Procedure pointer 'pps0' associated with result of reference to function 'null' that is an incompatible procedure pointer: distinct numbers of dummy arguments
dt2x = dt2(pps0=null(mold=dt3x%pps1))
!ERROR: Procedure pointer 'pps1' associated with result of reference to function 'null' that is an incompatible procedure pointer: distinct numbers of dummy arguments
dt3x = dt3(pps1=null(mold=dt2x%pps0))
dt3x = dt3(pps1=null(mold=dt3x%pps1))
dt4x = dt4(null()) ! ok
!PORTABILITY: NULL() with arguments is not standard conforming as the value for allocatable component 'ra0' [-Wnull-mold-allocatable-component-value]
dt4x = dt4(null(rp0))
!PORTABILITY: NULL() with arguments is not standard conforming as the value for allocatable component 'ra0' [-Wnull-mold-allocatable-component-value]
!ERROR: Rank-1 array value is not compatible with scalar component 'ra0'
dt4x = dt4(null(rp1))
!ERROR: A NULL procedure pointer may not be used as the value for component 'ra0'
dt4x = dt4(null(dt2x%pps0))
call canbenull(null(), null()) ! fine
call canbenull(null(mold=ip0), null(mold=rp0)) ! fine
!ERROR: ALLOCATABLE dummy argument 'x=' must be associated with an ALLOCATABLE actual argument
call optionalAllocatable(null(mold=ip0))
call optionalAllocatable(null(mold=ia0)) ! fine
call optionalAllocatable(null()) ! fine
!ERROR: Null pointer argument 'NULL()' requires an explicit interface
call implicit(null())
!ERROR: Null pointer argument 'null(mold=ip0)' requires an explicit interface
call implicit(null(mold=ip0))
!ERROR: A NULL() pointer is not allowed for 'x=' intrinsic argument
print *, sin(null(rp0))
!ERROR: A NULL() pointer is not allowed for 'x=' intrinsic argument
print *, kind(null())
print *, kind(null(rp0)) ! ok
!ERROR: A NULL() pointer is not allowed for 'a=' intrinsic argument
print *, extends_type_of(null(), null())
print *, extends_type_of(null(dt5p), null(dt4p)) ! ok
!ERROR: A NULL() pointer is not allowed for 'a=' intrinsic argument
print *, same_type_as(null(), null())
print *, same_type_as(null(dt5p), null(dt4p)) ! ok
!ERROR: A NULL() pointer is not allowed for 'source=' intrinsic argument
print *, transfer(null(rp0),ip0)
!WARNING: Source of TRANSFER contains allocatable or pointer component %ra0 [-Wpointer-component-transfer-arg]
print *, transfer(dt4(null()),[0])
!ERROR: NULL() may not be used as an expression in this context
select case(null(ip0))
end select
!ERROR: NULL() may not be used as an expression in this context
if (null(lp)) then
end if
end subroutine test
module m
type :: pdt(n)
integer, len :: n
end type
contains
subroutine s1(x)
character(*), pointer, intent(in) :: x
end
subroutine s2(x)
type(pdt(*)), pointer, intent(in) :: x
end
subroutine s3(ar)
real, pointer :: ar(..)
end
subroutine test(ar)
real, pointer :: ar(..)
!ERROR: Actual argument associated with dummy argument 'x=' is a NULL() pointer without a MOLD= to provide a character length
call s1(null())
!ERROR: Actual argument associated with dummy argument 'x=' is a NULL() pointer without a MOLD= to provide a value for the assumed type parameter 'n'
call s2(null())
!ERROR: MOLD= argument to NULL() must not be assumed-rank
call s3(null(ar))
end
end