Index: flang/include/flang/Evaluate/tools.h =================================================================== --- flang/include/flang/Evaluate/tools.h +++ flang/include/flang/Evaluate/tools.h @@ -1144,6 +1144,8 @@ // but identical derived types. bool AreTkCompatibleTypes(const DeclTypeSpec *x, const DeclTypeSpec *y); +bool HasConstantKindAndLen(const Symbol &); + } // namespace Fortran::semantics #endif // FORTRAN_EVALUATE_TOOLS_H_ Index: flang/lib/Evaluate/tools.cpp =================================================================== --- flang/lib/Evaluate/tools.cpp +++ flang/lib/Evaluate/tools.cpp @@ -1553,4 +1553,26 @@ return false; } +bool HasConstantKindAndLen(const Symbol &sym) { + if (const DeclTypeSpec * type{sym.GetType()}) { + if (type->category() == DeclTypeSpec::Numeric) { + if (evaluate::ToInt64(type->numericTypeSpec().kind())) { + return true; + } + } else if (type->category() == DeclTypeSpec::Logical) { + if (evaluate::ToInt64(type->logicalTypeSpec().kind())) { + return true; + } + } else if (type->category() == DeclTypeSpec::Character) { + if (evaluate::ToInt64(type->characterTypeSpec().kind())) { + if (const auto &length{ + type->characterTypeSpec().length().GetExplicit()}) { + return evaluate::IsConstantExpr(*length); + } + } + } + } + return false; +} + } // namespace Fortran::semantics Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -6675,7 +6675,8 @@ } else if (auto *details{ultimate.detailsIf()}) { CHECK(!details->init()); Walk(expr); - if (ultimate.owner().IsParameterizedDerivedType()) { + if (ultimate.owner().IsParameterizedDerivedType() && + !semantics::HasConstantKindAndLen(*name.symbol)) { // Save the expression for per-instantiation analysis. details->set_unanalyzedPDTComponentInit(&expr.thing.value()); } else { Index: flang/test/Semantics/init01.f90 =================================================================== --- flang/test/Semantics/init01.f90 +++ flang/test/Semantics/init01.f90 @@ -59,12 +59,10 @@ type :: t2(kind, len) integer, kind :: kind integer, len :: len -!ERROR: Dimension 1 of initialized object has extent 2, but initialization expression has extent 3 !ERROR: Dimension 1 of initialized object has extent 2, but initialization expression has extent 3 real :: x1(2) = [1., 2., 3.] -!ERROR: Dimension 1 of initialized object has extent 2, but initialization expression has extent 3 +!ERROR: Shape of initialized object 'x2' must be constant real :: x2(kind) = [1., 2., 3.] -!ERROR: Dimension 1 of initialized object has extent 2, but initialization expression has extent 3 !ERROR: Shape of initialized object 'x3' must be constant real :: x3(len) = [1., 2., 3.] real, pointer :: p1(:) => a1 Index: flang/test/Semantics/init02.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/init02.f90 @@ -0,0 +1,77 @@ +! RUN: %flang_fc1 -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s --check-prefix=SEMA_ON +! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix=SEMA_OFF + +!----------------- +! EXPECTEED OUTPUT +!----------------- + +!SEMA_ON: Name = 'x' +!SEMA_ON-NEXT: Initialization -> Constant -> Expr = '10_4' +!SEMA_ON-NEXT: | LiteralConstant -> IntLiteralConstant = '10' +!SEMA_ON: Name = 'll' +!SEMA_ON-NEXT: Initialization -> Constant -> Expr = '.true._4' +!SEMA_ON-NEXT: | LiteralConstant -> LogicalLiteralConstant +!SEMA_ON-NEXT: | | bool +!SEMA_ON: Name = 'r' +!SEMA_ON-NEXT: Initialization -> Constant -> Expr = '1._4' +!SEMA_ON-NEXT: | LiteralConstant -> RealLiteralConstant +!SEMA_ON-NEXT: | | Real = '1.0' +!SEMA_ON: Name = 'c' +!SEMA_ON-NEXT: Initialization -> Constant -> Expr = '(2._4,1._4)' +!SEMA_ON-NEXT: | LiteralConstant -> ComplexLiteralConstant +!SEMA_ON-NEXT: | | ComplexPart -> SignedRealLiteralConstant +!SEMA_ON-NEXT: | | | RealLiteralConstant +!SEMA_ON-NEXT: | | | | Real = '2.0' +!SEMA_ON-NEXT: | | ComplexPart -> SignedRealLiteralConstant +!SEMA_ON-NEXT: | | | RealLiteralConstant +!SEMA_ON-NEXT: | | | | Real = '1.0' +!SEMA_ON: Name = 's' +!SEMA_ON-NEXT: Initialization -> Constant -> Expr = '"s"' +!SEMA_ON-NEXT: | LiteralConstant -> CharLiteralConstant +!SEMA_ON-NEXT: | | string = 's' +!SEMA_ON: Name = 'x2' +!SEMA_ON-NEXT: ComponentArraySpec -> ExplicitShapeSpec +!SEMA_ON-NEXT: | SpecificationExpr -> Scalar -> Integer -> Expr = '2_4' +!SEMA_ON-NEXT: | | LiteralConstant -> IntLiteralConstant = '2' +!SEMA_ON-NEXT: Initialization -> Constant -> Expr = '10_4' +!SEMA_ON-NEXT: | LiteralConstant -> IntLiteralConstant = '10' + +!SEMA_OFF: Name = 'x' +!SEMA_OFF-NEXT: Initialization -> Constant -> Expr -> LiteralConstant -> IntLiteralConstant = '10' +!SEMA_OFF: Name = 'll' +!SEMA_OFF-NEXT: Initialization -> Constant -> Expr -> LiteralConstant -> LogicalLiteralConstant +!SEMA_OFF-NEXT: | bool +!SEMA_OFF: Name = 'r' +!SEMA_OFF-NEXT: Initialization -> Constant -> Expr -> LiteralConstant -> RealLiteralConstant +!SEMA_OFF-NEXT: | Real = '1.0' +!SEMA_OFF: Name = 'c' +!SEMA_OFF-NEXT: Initialization -> Constant -> Expr -> LiteralConstant -> ComplexLiteralConstant +!SEMA_OFF-NEXT: | ComplexPart -> SignedRealLiteralConstant +!SEMA_OFF-NEXT: | | RealLiteralConstant +!SEMA_OFF-NEXT: | | | Real = '2.0' +!SEMA_OFF-NEXT: | ComplexPart -> SignedRealLiteralConstant +!SEMA_OFF-NEXT: | | RealLiteralConstant +!SEMA_OFF-NEXT: | | | Real = '1.0' +!SEMA_OFF: Name = 's' +!SEMA_OFF-NEXT: Initialization -> Constant -> Expr -> LiteralConstant -> CharLiteralConstant +!SEMA_OFF-NEXT: | string = 's' +!SEMA_OFF: Name = 'x2' +!SEMA_OFF-NEXT: ComponentArraySpec -> ExplicitShapeSpec +!SEMA_OFF-NEXT: | SpecificationExpr -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '2' +!SEMA_OFF-NEXT: Initialization -> Constant -> Expr -> LiteralConstant -> IntLiteralConstant = '10' + +!------- +! INPUT +!------- +subroutine sub() + type my_type (k, l) + integer, KIND :: k = 4 + integer, LEN :: l = 4 + integer :: x = 10 + logical :: ll = .true. + real :: r = 1.0 + complex :: c = (2.0, 1.0) + character :: s = "s" + integer :: x2(2) = 10 + end type +end