diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index a3be50ac072d4..5981116a6d3f7 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -236,6 +236,12 @@ class HlfirDesignatorBuilder { isVolatile = true; } + // Check if the base type is volatile + if (partInfo.base.has_value()) { + mlir::Type baseType = partInfo.base.value().getType(); + isVolatile = isVolatile || fir::isa_volatile_type(baseType); + } + // Arrays with non default lower bounds or dynamic length or dynamic extent // need a fir.box to hold the dynamic or lower bound information. if (fir::hasDynamicSize(resultValueType) || @@ -249,12 +255,6 @@ class HlfirDesignatorBuilder { /*namedConstantSectionsAreAlwaysContiguous=*/false)) return fir::BoxType::get(resultValueType, isVolatile); - // Check if the base type is volatile - if (partInfo.base.has_value()) { - mlir::Type baseType = partInfo.base.value().getType(); - isVolatile = fir::isa_volatile_type(baseType); - } - // Other designators can be handled as raw addresses. return fir::ReferenceType::get(resultValueType, isVolatile); } diff --git a/flang/test/Lower/volatile-derived-type.f90 b/flang/test/Lower/volatile-derived-type.f90 new file mode 100644 index 0000000000000..edd77a9265530 --- /dev/null +++ b/flang/test/Lower/volatile-derived-type.f90 @@ -0,0 +1,48 @@ +! RUN: bbc --strict-fir-volatile-verifier %s -o - | FileCheck %s +! Ensure member access of a volatile derived type is volatile. + type t + integer :: e(4)=2 + end type t + type(t), volatile :: f + call test (f%e(::2)) +contains + subroutine test(v) + integer, asynchronous :: v(:) + end subroutine +end +! CHECK-LABEL: func.func @_QQmain() { +! CHECK: %[[VAL_0:.*]] = arith.constant 4 : index +! CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_5:.*]] = fir.address_of(@_QFE.b.t.e) : !fir.ref,value:i64}>>> +! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_3]], %[[VAL_2]], %[[VAL_3]], %[[VAL_1]] : (index, index, index, index) -> !fir.shapeshift<2> +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]](%[[VAL_6]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.b.t.e"} : +! CHECK: %[[VAL_8:.*]] = fir.address_of(@_QFE.n.e) : !fir.ref> +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] typeparams %[[VAL_1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.n.e"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QFE.di.t.e) : !fir.ref> +! CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]](%[[VAL_11]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.di.t.e"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_13:.*]] = fir.address_of(@_QFE.n.t) : !fir.ref> +! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_13]] typeparams %[[VAL_1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.n.t"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_15:.*]] = fir.alloca !fir.type<_QFTt{e:!fir.array<4xi32>}> {bindc_name = "f", uniq_name = "_QFEf"} +! CHECK: %[[VAL_16:.*]] = fir.volatile_cast %[[VAL_15]] : (!fir.ref}>>) -> !fir.ref}>, volatile> +! CHECK: %[[VAL_17:.*]]:2 = hlfir.declare %[[VAL_16]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEf"} : (!fir.ref}>, volatile>) -> (!fir.ref}>, volatile>, !fir.ref}>, volatile>) +! CHECK: %[[VAL_18:.*]] = fir.address_of(@_QQ_QFTt.DerivedInit) : !fir.ref}>> +! CHECK: fir.copy %[[VAL_18]] to %[[VAL_17]]#0 no_overlap : !fir.ref}>>, !fir.ref}>, volatile> +! CHECK: %[[VAL_20:.*]] = fir.shape_shift %[[VAL_3]], %[[VAL_1]] : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %{{.+}}(%[[VAL_20]]) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFE.c.t"} : +! CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_17]]#0{"e"} <%[[VAL_11]]> (%[[VAL_1]]:%[[VAL_0]]:%[[VAL_2]]) shape %[[VAL_24]] : (!fir.ref}>, volatile>, !fir.shape<1>, index, index, index, !fir.shape<1>) -> !fir.box, volatile> +! CHECK: %[[VAL_26:.*]] = fir.volatile_cast %[[VAL_25]] : (!fir.box, volatile>) -> !fir.box> +! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.box>) -> !fir.box> +! CHECK: fir.call @_QFPtest(%[[VAL_27]]) fastmath : (!fir.box>) -> () +! CHECK: return +! CHECK: } +! CHECK-LABEL: func.func private @_QFPtest( +! CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box> {fir.asynchronous, fir.bindc_name = "v"}) attributes {fir.host_symbol = @_QQmain, llvm.linkage = #llvm.linkage} { +! CHECK: %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFFtestEv"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: return +! CHECK: }