[flang-commits] [flang] [flang] Add structure constructor with allocatable component (PR #77845)

via flang-commits flang-commits at lists.llvm.org
Thu Jan 11 14:49:57 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Kelvin Li (kkwli)

<details>
<summary>Changes</summary>

This PR is to enable the structure constructor with allocatable component support. Handling of `null()` for the allocatable component is added.

A separate PR will be created for enabling the related test cases in llvm-test-suite.

---
Full diff: https://github.com/llvm/llvm-project/pull/77845.diff


7 Files Affected:

- (modified) flang/lib/Evaluate/check-expression.cpp (+6) 
- (modified) flang/lib/Evaluate/fold.cpp (+5) 
- (modified) flang/lib/Lower/ConvertConstant.cpp (+13-2) 
- (added) flang/test/Lower/structure-constructors-alloc-comp.f90 (+120) 
- (modified) flang/test/Semantics/structconst06.f90 (+1) 
- (modified) flang/test/Semantics/structconst07.f90 (+6) 
- (added) flang/test/Semantics/structconst08.f90 (+57) 


``````````diff
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 2f46ed7dccb645..2e8a6589806c2a 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -188,6 +188,12 @@ struct IsActuallyConstantHelper {
     return common::visit([this](const auto &y) { return (*this)(y); }, x.u);
   }
   bool operator()(const StructureConstructor &x) {
+    // If the comp-spec of a derived-type-spec is a structure constructor that
+    // is not a constant, the derived-type-spec is not a constant
+    if (!UnwrapExpr<Constant<SomeDerived>>(x)) {
+      return false;
+    }
+
     for (const auto &pair : x) {
       const Expr<SomeType> &y{pair.second.value()};
       if (!(*this)(y) && !IsNullPointer(y)) {
diff --git a/flang/lib/Evaluate/fold.cpp b/flang/lib/Evaluate/fold.cpp
index dfcc2599a555e5..ed882958199802 100644
--- a/flang/lib/Evaluate/fold.cpp
+++ b/flang/lib/Evaluate/fold.cpp
@@ -82,6 +82,11 @@ Expr<SomeDerived> FoldOperation(
       } else {
         isConstant &= IsInitialDataTarget(expr);
       }
+    } else if (IsAllocatable(symbol)) {
+      // F2023: 10.1.12 (3)(a)
+      // If comp-spec is not null() for the allocatable component the
+      // structure constructor is not a constant expression.
+      isConstant &= IsNullPointer(expr);
     } else {
       isConstant &= IsActuallyConstant(expr) || IsNullPointer(expr);
       if (auto valueShape{GetConstantExtents(context, expr)}) {
diff --git a/flang/lib/Lower/ConvertConstant.cpp b/flang/lib/Lower/ConvertConstant.cpp
index d7a4d68f2aaae7..2efacd4e2db959 100644
--- a/flang/lib/Lower/ConvertConstant.cpp
+++ b/flang/lib/Lower/ConvertConstant.cpp
@@ -18,6 +18,7 @@
 #include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/Mangler.h"
 #include "flang/Optimizer/Builder/Complex.h"
+#include "flang/Optimizer/Builder/MutableBox.h"
 #include "flang/Optimizer/Builder/Todo.h"
 
 #include <algorithm>
@@ -362,8 +363,18 @@ static mlir::Value genStructureComponentInit(
       loc, fieldTy, name, recTy,
       /*typeParams=*/mlir::ValueRange{} /*TODO*/);
 
-  if (Fortran::semantics::IsAllocatable(sym))
-    TODO(loc, "allocatable component in structure constructor");
+  if (Fortran::semantics::IsAllocatable(sym)) {
+    if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(expr)) {
+      // Handle NULL() initialization
+      mlir::Value componentValue{fir::factory::createUnallocatedBox(
+          builder, loc, componentTy, std::nullopt)};
+      componentValue = builder.createConvert(loc, componentTy, componentValue);
+
+      return builder.create<fir::InsertValueOp>(
+          loc, recTy, res, componentValue,
+          builder.getArrayAttr(field.getAttributes()));
+    }
+  }
 
   if (Fortran::semantics::IsPointer(sym)) {
     if (Fortran::semantics::IsProcedure(sym))
diff --git a/flang/test/Lower/structure-constructors-alloc-comp.f90 b/flang/test/Lower/structure-constructors-alloc-comp.f90
new file mode 100644
index 00000000000000..49270bcd5288a1
--- /dev/null
+++ b/flang/test/Lower/structure-constructors-alloc-comp.f90
@@ -0,0 +1,120 @@
+! Test lowering of structure constructors of derived types with allocatable component
+! RUN: bbc -emit-hlfir %s -o - | FileCheck --check-prefixes=HLFIR %s
+
+module m_struct_ctor
+  implicit none
+  type t_alloc
+    real :: x
+    integer, allocatable :: a(:)
+  end type
+
+contains
+  subroutine test_alloc1(y)
+    real :: y
+    call print_alloc_comp(t_alloc(x=y, a=null()))
+! HLFIR-LABEL:  func.func @_QMm_struct_ctorPtest_alloc1(
+! HLFIR-SAME:      %[[ARG_0:.*]]: !fir.ref<f32> {fir.bindc_name = "y"}) {
+! HLFIR:    %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
+! HLFIR:    %[[VAL_1:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
+! HLFIR:    %[[CONS_1:.*]] = arith.constant 1 : index
+! HLFIR:    %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {{.*}}"_QMm_struct_ctorE.n.x"
+! HLFIR:    %[[VAL_3:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
+! HLFIR:    %[[CONS_2:.* ]]= arith.constant 1 : index
+! HLFIR:    %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {{.*}}"_QMm_struct_ctorE.n.a"
+! HLFIR:    %[[VAL_5:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
+! HLFIR:    %[[CONS_3:.*]] = arith.constant 7 : index
+! HLFIR:    %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {{.*}}"_QMm_struct_ctorE.n.t_alloc"
+! HLFIR:    %[[VAL_7:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc)
+! HLFIR:    %[[CONS_4:.*]] = arith.constant 0 : index
+! HLFIR:    %[[CONS_5:.*]] = arith.constant 2 : index
+! HLFIR:    %[[VAL_8:.*]] = fir.shape_shift %[[CONS_4]], %[[CONS_5]] : (index, index) -> !fir.shapeshift<1>
+! HLFIR:    %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
+! HLFIR:    %[[VAL_10:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc)
+! HLFIR:    %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
+! HLFIR:    %[[VAL_12:.*]]:2 = hlfir.declare %[[ARG_0]] {uniq_name = "_QMm_struct_ctorFtest_alloc1Ey"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! HLFIR:    %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
+! HLFIR:    %[[VAL_14:.*]] = fir.embox %[[VAL_13]]#0 : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+! HLFIR:    %[[VAL_15:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+! HLFIR:    %[[CONS_6:.*]] = arith.constant {{.*}} : i32
+! HLFIR:    %[[VAL_16:.*]] = fir.convert %[[VAL_14]] : (!fir.box<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<none>
+! HLFIR:    %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+! HLFIR:    %{{.*}} = fir.call @_FortranAInitialize(%[[VAL_16]], %[[VAL_17]], %[[CONS_6]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> none
+! HLFIR:    %[[VAL_18:.*]] = hlfir.designate %[[VAL_13]]#0{"x"}   : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<f32>
+! HLFIR:    %[[VAL_19:.*]] = fir.load %[[VAL_12]]#0 : !fir.ref<f32>
+! HLFIR:    hlfir.assign %[[VAL_19]] to %[[VAL_18]] temporary_lhs : f32, !fir.ref<f32>
+! HLFIR:    fir.call @_QPprint_alloc_comp(%[[VAL_13]]#1) fastmath<contract> : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> ()
+! HLFIR:    return
+! HLFIR:  }
+  end subroutine
+  
+  subroutine test_alloc2(y, b)
+    real :: y
+    integer :: b(5)
+    call print_alloc_comp(t_alloc(x=y, a=b))
+! HLFIR-LABEL:  func.func @_QMm_struct_ctorPtest_alloc2
+! HLFIR-SAME:     (%[[ARG_0:.*]]: !fir.ref<f32> {fir.bindc_name = "y"}, %[[ARG_1:.*]]: !fir.ref<!fir.array<5xi32>> {fir.bindc_name = "b"}) {
+! HLFIR:    %[[VAL_0:.*]] = fir.alloca !fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
+! HLFIR:    %[[VAL_1:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
+! HLFIR:    %[[CONS_1:.*]] = arith.constant 1 : index
+! HLFIR:    %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] typeparams %[[CONS_1]] {{.*}}"_QMm_struct_ctorE.n.x"
+! HLFIR:    %[[VAL_3:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
+! HLFIR:    %[[CONS_2:.*]] = arith.constant 1 : index
+! HLFIR:    %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] typeparams %[[CONS_2]] {{.*}}"_QMm_struct_ctorE.n.a"
+! HLFIR:    %[[VAL_5:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
+! HLFIR:    %[[CONS_3:.*]] = arith.constant 7 : index
+! HLFIR:    %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[CONS_3]] {{.*}}"_QMm_struct_ctorE.n.t_alloc"
+! HLFIR:    %[[VAL_7:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc)
+! HLFIR:    %[[CONS_4:.*]] = arith.constant 0 : index
+! HLFIR:    %[[CONS_5:.*]] = arith.constant 2 : index
+! HLFIR:    %[[VAL_8:.*]] = fir.shape_shift %[[CONS_4]], %[[CONS_5]] : (index, index) -> !fir.shapeshift<1>
+! HLFIR:    %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
+! HLFIR:    %[[VAL_10:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc)
+! HLFIR:    %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
+! HLFIR:    %[[CONS_6:.*]] = arith.constant 5 : index
+! HLFIR:    %[[VAL_12:.*]] = fir.shape %[[CONS_6]] : (index) -> !fir.shape<1>
+! HLFIR:    %[[VAL_13:.*]]:2 = hlfir.declare %[[ARG_1]](%[[VAL_12]]) {uniq_name = "_QMm_struct_ctorFtest_alloc2Eb"} : (!fir.ref<!fir.array<5xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>)
+! HLFIR:    %[[VAL_14:.*]]:2 = hlfir.declare %[[ARG_0]] {uniq_name = "_QMm_struct_ctorFtest_alloc2Ey"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! HLFIR:    %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>)
+! HLFIR:    %[[VAL_16:.*]] = fir.embox %[[VAL_15]]#0 : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+! HLFIR:    %[[VAL_17:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+! HLFIR:    %[[CONS_7:.*]] = arith.constant {{.*}} : i32
+! HLFIR:    %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<none>
+! HLFIR:    %[[VAL_19:.*]] = fir.convert %[[VAL_17]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+! HLFIR:    {{.*}} = fir.call @_FortranAInitialize(%[[VAL_18]], %[[VAL_19]], %[[CONS_7]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> none
+! HLFIR:    %[[VAL_20:.*]] = hlfir.designate %[[VAL_15]]#0{"x"}   : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<f32>
+! HLFIR:    %[[VAL_21:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref<f32>
+! HLFIR:    hlfir.assign %[[VAL_21]] to %[[VAL_20]] temporary_lhs : f32, !fir.ref<f32>
+! HLFIR:    %[[VAL_22:.*]] = hlfir.designate %[[VAL_15]]#0{"a"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! HLFIR:    hlfir.assign %[[VAL_13]]#0 to %[[VAL_22]] realloc temporary_lhs : !fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! HLFIR:    fir.call @_QPprint_alloc_comp(%[[VAL_15]]#1) fastmath<contract> : (!fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> ()
+! HLFIR:    return
+! HLFIR:  }
+  end subroutine
+
+  subroutine test_alloc3()
+    type(t_alloc) :: t1 = t_alloc(x=5, a=null())
+! HLFIR-LABEL:  func.func @_QMm_struct_ctorPtest_alloc3() {
+! HLFIR:    %[[VAL_0:.*]] = fir.address_of(@_QMm_struct_ctorE.n.x) : !fir.ref<!fir.char<1>>
+! HLFIR:    %c1 = arith.constant 1 : index
+! HLFIR:    %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %c1 {{.*}}"_QMm_struct_ctorE.n.x"
+! HLFIR:    %[[VAL_2:.*]] = fir.address_of(@_QMm_struct_ctorE.n.a) : !fir.ref<!fir.char<1>>
+! HLFIR:    %c1_0 = arith.constant 1 : index
+! HLFIR:    %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %c1_0 {{.*}}"_QMm_struct_ctorE.n.a"
+! HLFIR:    %[[VAL_4:.*]] = fir.address_of(@_QMm_struct_ctorE.n.t_alloc) : !fir.ref<!fir.char<1,7>>
+! HLFIR:    %c7 = arith.constant 7 : index
+! HLFIR:    %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] typeparams %c7 {{.*}}"_QMm_struct_ctorE.n.t_alloc"
+! HLFIR:    %[[VAL_6:.*]] = fir.address_of(@_QMm_struct_ctorE.c.t_alloc) 
+! HLFIR:    %c0 = arith.constant 0 : index
+! HLFIR:    %c2 = arith.constant 2 : index
+! HLFIR:    %[[VAL_7:.*]] = fir.shape_shift %c0, %c2 : (index, index) -> !fir.shapeshift<1>
+! HLFIR:    %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]](%[[VAL_7]]) {{.*}}"_QMm_struct_ctorE.c.t_alloc"
+! HLFIR:    %[[VAL_9:.*]] = fir.address_of(@_QMm_struct_ctorE.dt.t_alloc) 
+! HLFIR:    %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_9]] {{.*}}"_QMm_struct_ctorE.dt.t_alloc"
+! HLFIR:    %[[VAL_11:.*]] = fir.address_of(@_QMm_struct_ctorFtest_alloc3Et1) : !fir.ref<!fir.type<_QMm_struct_ctorTt_alloc{x:f32,a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+! HLFIR:    {{.*}}:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QMm_struct_ctorFtest_alloc3Et1"} 
+! HLFIR:    return
+! HLFIR:  }
+
+  end subroutine
+
+end module m_struct_ctor
diff --git a/flang/test/Semantics/structconst06.f90 b/flang/test/Semantics/structconst06.f90
index d5a40410ea63a1..45a0fb97842d30 100644
--- a/flang/test/Semantics/structconst06.f90
+++ b/flang/test/Semantics/structconst06.f90
@@ -4,6 +4,7 @@ module m
   type t
     real, allocatable :: a(:)
   end type
+  !ERROR: Must be a constant value
   !ERROR: Scalar value cannot be expanded to shape of array component 'a'
   type(t) :: x = t(0.)
 end module
diff --git a/flang/test/Semantics/structconst07.f90 b/flang/test/Semantics/structconst07.f90
index a34289a817af44..d61c54200dc82d 100644
--- a/flang/test/Semantics/structconst07.f90
+++ b/flang/test/Semantics/structconst07.f90
@@ -2,8 +2,14 @@
 type :: hasPointer
   class(*), pointer :: sp
 end type
+type :: hasAllocatable
+  class(*), allocatable :: sa
+end type
 type(hasPointer) hp
+type(hasAllocatable) ha
 !CHECK: hp=haspointer(sp=NULL())
 hp = hasPointer()
+!CHECK: ha=hasallocatable(sa=NULL())
+ha = hasAllocatable()
 end
 
diff --git a/flang/test/Semantics/structconst08.f90 b/flang/test/Semantics/structconst08.f90
new file mode 100644
index 00000000000000..211b0e79bf5e44
--- /dev/null
+++ b/flang/test/Semantics/structconst08.f90
@@ -0,0 +1,57 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
+!
+! Error tests for structure constructors of derived types with allocatable components
+
+module m
+  type parent1
+    integer, allocatable :: pa
+  end type parent1
+  type parent2
+    real, allocatable :: pa(:)
+  end type parent2
+  type child
+    integer :: i
+    type(parent2) :: ca
+  end type
+
+contains
+  subroutine test1()
+    integer :: j
+    real :: arr(5)
+!ERROR: Must be a constant value
+    type(parent1) :: tp1 = parent1(3)
+!ERROR: Must be a constant value
+    type(parent1) :: tp2 = parent1(j)
+    type(parent1) :: tp3 = parent1(null())
+
+!ERROR: Must be a constant value
+    type(parent2) :: tp4 = parent2([1.1,2.1,3.1])
+!ERROR: Must be a constant value
+    type(parent2) :: tp5 = parent2(arr)
+    type(parent2) :: tp6 = parent2(null())
+  end subroutine test1
+
+  subroutine test2()
+    integer :: j
+    real :: arr(5)
+    type(parent1) :: tp1
+    type(parent2) :: tp2
+    tp1 = parent1(3)
+    tp1 = parent1(j)
+    tp1 = parent1(null())
+
+    tp2 = parent2([1.1,2.1,3.1])
+    tp2 = parent2(arr)
+    tp2 = parent2(null())
+  end subroutine test2
+
+  subroutine test3()
+    type(child) :: tc1 = child(5, parent2(null()))
+!ERROR: Must be a constant value
+    type(child) :: tc2 = child(5, parent2([1.1,1.2]))
+    type(child) :: tc3
+
+    tc3 = child(5, parent2(null()))
+    tc3 = child(5, parent2([1.1,1.2]))
+  end subroutine test3
+end module m

``````````

</details>


https://github.com/llvm/llvm-project/pull/77845


More information about the flang-commits mailing list