In some contexts, including the motivating case of determining whether the expressions that define the shape of a variable are "constant expressions" in the sense of the Fortran standard, expression rewriting via Fold() is not necessary, and should not be required. The inquiry intrinsics LBOUND, UBOUND, and SIZE work correctly now in specification expressions and are classified correctly as being constant expressions (or not). Getting this right led to a fair amount of API clean-up as a consequence, including the folding of shapes and TypeAndShape objects, and new APIs for shapes that do not fold for those cases where folding isn't needed. Further, the symbol-testing predicate APIs in Evaluate/tools.h now all resolve any associations of their symbols and work transparently on use-, host-, and construct-association symbols; the tools used to resolve those associations have been defined and documented more precisely, and their clients adjusted as needed. Differential Revision: https://reviews.llvm.org/D94561
49 lines
2.1 KiB
Fortran
49 lines
2.1 KiB
Fortran
! RUN: %S/test_errors.sh %s %t %f18
|
|
! Error tests for recursive use of derived types.
|
|
! C744 If neither the POINTER nor the ALLOCATABLE attribute is specified, the
|
|
! declaration-type-spec in the component-def-stmt shall specify an intrinsic
|
|
! type or a previously defined derived type.
|
|
|
|
program main
|
|
type :: recursive1
|
|
!ERROR: Recursive use of the derived type requires POINTER or ALLOCATABLE
|
|
type(recursive1) :: bad1
|
|
type(recursive1), pointer :: ok1
|
|
type(recursive1), allocatable :: ok2
|
|
!ERROR: Recursive use of the derived type requires POINTER or ALLOCATABLE
|
|
!ERROR: CLASS entity 'bad2' must be a dummy argument or have ALLOCATABLE or POINTER attribute
|
|
class(recursive1) :: bad2
|
|
class(recursive1), pointer :: ok3
|
|
class(recursive1), allocatable :: ok4
|
|
end type recursive1
|
|
type :: recursive2(kind,len)
|
|
integer, kind :: kind
|
|
integer, len :: len
|
|
!ERROR: Recursive use of the derived type requires POINTER or ALLOCATABLE
|
|
type(recursive2(kind,len)) :: bad1
|
|
type(recursive2(kind,len)), pointer :: ok1
|
|
type(recursive2(kind,len)), allocatable :: ok2
|
|
!ERROR: Recursive use of the derived type requires POINTER or ALLOCATABLE
|
|
!ERROR: CLASS entity 'bad2' must be a dummy argument or have ALLOCATABLE or POINTER attribute
|
|
class(recursive2(kind,len)) :: bad2
|
|
class(recursive2(kind,len)), pointer :: ok3
|
|
class(recursive2(kind,len)), allocatable :: ok4
|
|
end type recursive2
|
|
type :: recursive3(kind,len)
|
|
integer, kind :: kind = 1
|
|
integer, len :: len = 2
|
|
!ERROR: Recursive use of the derived type requires POINTER or ALLOCATABLE
|
|
type(recursive3) :: bad1
|
|
type(recursive3), pointer :: ok1
|
|
type(recursive3), allocatable :: ok2
|
|
!ERROR: Recursive use of the derived type requires POINTER or ALLOCATABLE
|
|
!ERROR: CLASS entity 'bad2' must be a dummy argument or have ALLOCATABLE or POINTER attribute
|
|
class(recursive3) :: bad2
|
|
class(recursive3), pointer :: ok3
|
|
class(recursive3), allocatable :: ok4
|
|
end type recursive3
|
|
!ERROR: Derived type 'recursive4' cannot extend itself
|
|
type, extends(recursive4) :: recursive4
|
|
end type recursive4
|
|
end program main
|