void Post(const parser::DimensionStmt::Declaration &);
void Post(const parser::CodimensionDecl &);
bool Pre(const parser::TypeDeclarationStmt &) { return BeginDecl(); }
- void Post(const parser::TypeDeclarationStmt &) { EndDecl(); }
+ void Post(const parser::TypeDeclarationStmt &);
void Post(const parser::IntegerTypeSpec &);
void Post(const parser::IntrinsicTypeSpec::Real &);
void Post(const parser::IntrinsicTypeSpec::Complex &);
return false;
}
+void DeclarationVisitor::Post(const parser::TypeDeclarationStmt &) {
+ if (!GetAttrs().HasAny({Attr::POINTER, Attr::ALLOCATABLE})) { // C702
+ if (const auto *typeSpec{GetDeclTypeSpec()}) {
+ if (typeSpec->category() == DeclTypeSpec::Character) {
+ if (typeSpec->characterTypeSpec().length().isDeferred()) {
+ Say("The type parameter LEN cannot be deferred without"
+ " the POINTER or ALLOCATABLE attribute"_err_en_US);
+ }
+ } else if (const DerivedTypeSpec * derivedSpec{typeSpec->AsDerived()}) {
+ for (const auto &pair : derivedSpec->parameters()) {
+ if (pair.second.isDeferred()) {
+ Say(currStmtSource().value(),
+ "The value of type parameter '%s' cannot be deferred"
+ " without the POINTER or ALLOCATABLE attribute"_err_en_US,
+ pair.first);
+ }
+ }
+ }
+ }
+ }
+ EndDecl();
+}
+
void DeclarationVisitor::Post(const parser::DimensionStmt::Declaration &x) {
const auto &name{std::get<parser::Name>(x.t)};
DeclareObjectEntity(name, Attrs{});
// so POINTER & ALLOCATABLE enable forward references to derived types.
Walk(std::get<std::list<parser::ComponentAttrSpec>>(x.t));
set_allowForwardReferenceToDerivedType(
- GetAttrs().test(Attr::POINTER) || GetAttrs().test(Attr::ALLOCATABLE));
+ GetAttrs().HasAny({Attr::POINTER, Attr::ALLOCATABLE}));
Walk(std::get<parser::DeclarationTypeSpec>(x.t));
set_allowForwardReferenceToDerivedType(false);
Walk(std::get<std::list<parser::ComponentDecl>>(x.t));
resolve66.f90
resolve67.f90
resolve68.f90
+ resolve69.f90
stop01.f90
structconst01.f90
structconst02.f90
type(SomeType(1, l1=3)), pointer :: cp9, cp10(:)
type(B(*)) b1
- type(B(:)) b2
+ type(B(:)), allocatable :: b2
type(B(5)) b3
type(SomeType(4, *, 8)) bsrc
real(kind=8) srcx8, srcx8_array(10)
class(WithParam(4, 2)) src_a_4_2
type(WithParam(8, 2)) src_a_8_2
- class(WithParam(4, :)) src_a_4_def
- class(WithParam(8, :)) src_a_8_def
+ class(WithParam(4, :)), allocatable :: src_a_4_def
+ class(WithParam(8, :)), allocatable :: src_a_8_def
type(WithParamExtent(4, 2, 8, 3)) src_b_4_2_8_3
- class(WithParamExtent(4, :, 8, 3)) src_b_4_def_8_3
+ class(WithParamExtent(4, :, 8, 3)), allocatable :: src_b_4_def_8_3
type(WithParamExtent(8, 2, 8, 3)) src_b_8_2_8_3
- class(WithParamExtent(8, :, 8, 3)) src_b_8_def_8_3
+ class(WithParamExtent(8, :, 8, 3)), allocatable :: src_b_8_def_8_3
type(WithParamExtent2(k1=4, l1=5, k2=5, l2=6, l3=8 )) src_c_4_5_5_6_8_8
class(WithParamExtent2(k1=4, l1=2, k2=5, l2=6, k3=5, l3=8)) src_c_4_2_5_6_5_8
class(WithParamExtent2(k2=5, l2=6, k3=5, l3=8)) src_c_1_2_5_6_5_8
! Note: Module files are encoded in UTF-8.
module m
-character(kind=4,len=:), parameter :: c4 = 4_"Hi! 你好!"
+character(kind=4,len=*), parameter :: c4 = 4_"Hi! 你好!"
! In CHARACTER(1) literals, codepoints > 0xff are serialized into UTF-8;
! each of those bytes then gets encoded into UTF-8 for the module file.
-character(kind=1,len=:), parameter :: c1 = 1_"Hi! 你好!"
-character(kind=4,len=:), parameter :: c4a(*) = [4_"一", 4_"二", 4_"三", 4_"四", 4_"五"]
+character(kind=1,len=*), parameter :: c1 = 1_"Hi! 你好!"
+character(kind=4,len=*), parameter :: c4a(*) = [4_"一", 4_"二", 4_"三", 4_"四", 4_"五"]
integer, parameter :: lc4 = len(c4)
integer, parameter :: lc1 = len(c1)
end module m
!Expect: m.mod
!module m
-!character(:,4),parameter::c4=4_"Hi! \344\275\240\345\245\275!"
-!character(:,1),parameter::c1=1_"Hi! \344\275\240\345\245\275!"
-!character(:,4),parameter::c4a(1_8:*)=[CHARACTER(KIND=4,LEN=1)::4_"\344\270\200",4_"\344\272\214",4_"\344\270\211",4_"\345\233\233",4_"\344\272\224"]
+!character(*,4),parameter::c4=4_"Hi! \344\275\240\345\245\275!"
+!character(*,1),parameter::c1=1_"Hi! \344\275\240\345\245\275!"
+!character(*,4),parameter::c4a(1_8:*)=[CHARACTER(KIND=4,LEN=1)::4_"\344\270\200",4_"\344\272\214",4_"\344\270\211",4_"\345\233\233",4_"\344\272\224"]
!integer(4),parameter::lc4=7_4
!intrinsic::len
!integer(4),parameter::lc1=11_4
+! C701 The type-param-value for a kind type parameter shall be a constant
+! expression. This constraint looks like a mistake in the standard.
integer, parameter :: k = 8
real, parameter :: l = 8.0
integer :: n = 2
--- /dev/null
+subroutine s1()
+ ! C701 (R701) The type-param-value for a kind type parameter shall be a
+ ! constant expression.
+ ! C702 (R701) A colon shall not be used as a type-param-value except in the
+ ! declaration of an entity that has the POINTER or ALLOCATABLE attribute.
+ integer, parameter :: constVal = 1
+ integer :: nonConstVal = 1
+!ERROR: Invalid specification expression: reference to local entity 'nonconstval'
+ character(nonConstVal) :: colonString1
+ character(len=20, kind=constVal + 1) :: constKindString
+ character(len=:, kind=constVal + 1), pointer :: constKindString1
+!ERROR: The type parameter LEN cannot be deferred without the POINTER or ALLOCATABLE attribute
+ character(len=:, kind=constVal + 1) :: constKindString2
+!ERROR: Must be a constant value
+ character(len=20, kind=nonConstVal) :: nonConstKindString
+!ERROR: The type parameter LEN cannot be deferred without the POINTER or ALLOCATABLE attribute
+ character(len=:) :: deferredString
+!ERROR: The type parameter LEN cannot be deferred without the POINTER or ALLOCATABLE attribute
+ character(:) :: colonString2
+ !OK because of the allocatable attribute
+ character(:), allocatable :: colonString3
+
+ type derived(typeKind, typeLen)
+ integer, kind :: typeKind
+ integer, len :: typeLen
+ end type derived
+
+ type (derived(constVal, 3)) :: constDerivedKind
+!ERROR: Value of kind type parameter 'typekind' (nonconstval) is not a scalar INTEGER constant
+!ERROR: Invalid specification expression: reference to local entity 'nonconstval'
+ type (derived(nonConstVal, 3)) :: nonConstDerivedKind
+
+ !OK because all type-params are constants
+ type (derived(3, constVal)) :: constDerivedLen
+
+!ERROR: Invalid specification expression: reference to local entity 'nonconstval'
+ type (derived(3, nonConstVal)) :: nonConstDerivedLen
+!ERROR: The value of type parameter 'typelen' cannot be deferred without the POINTER or ALLOCATABLE attribute
+ type (derived(3, :)) :: colonDerivedLen
+!ERROR: The value of type parameter 'typekind' cannot be deferred without the POINTER or ALLOCATABLE attribute
+!ERROR: The value of type parameter 'typelen' cannot be deferred without the POINTER or ALLOCATABLE attribute
+ type (derived( :, :)) :: colonDerivedLen1
+ type (derived( :, :)), pointer :: colonDerivedLen2
+ type (derived(4, :)), pointer :: colonDerivedLen3
+end subroutine s1