diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 5981116a6d3f7..04b63f92a1fb4 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -205,17 +205,8 @@ class HlfirDesignatorBuilder { partInfo.resultShape = hlfir::genShape(getLoc(), getBuilder(), *partInfo.base); - // Dynamic type of polymorphic base must be kept if the designator is - // polymorphic. - if (isPolymorphic(designatorNode)) - return fir::ClassType::get(resultValueType); - // Character scalar with dynamic length needs a fir.boxchar to hold the - // designator length. - auto charType = mlir::dyn_cast(resultValueType); - if (charType && charType.hasDynamicLen()) - return fir::BoxCharType::get(charType.getContext(), charType.getFKind()); - - // When volatile is enabled, enable volatility on the designatory type. + // Enable volatility on the designatory type if it has the VOLATILE + // attribute or if the base is volatile. bool isVolatile = false; // Check if this should be a volatile reference @@ -236,6 +227,17 @@ class HlfirDesignatorBuilder { isVolatile = true; } + // Dynamic type of polymorphic base must be kept if the designator is + // polymorphic. + if (isPolymorphic(designatorNode)) + return fir::ClassType::get(resultValueType, isVolatile); + + // Character scalar with dynamic length needs a fir.boxchar to hold the + // designator length. + auto charType = mlir::dyn_cast(resultValueType); + if (charType && charType.hasDynamicLen()) + return fir::BoxCharType::get(charType.getContext(), charType.getFKind()); + // Check if the base type is volatile if (partInfo.base.has_value()) { mlir::Type baseType = partInfo.base.value().getType(); diff --git a/flang/test/Lower/volatile-derived-type-pointer.f90 b/flang/test/Lower/volatile-derived-type-pointer.f90 new file mode 100644 index 0000000000000..64c4e64784510 --- /dev/null +++ b/flang/test/Lower/volatile-derived-type-pointer.f90 @@ -0,0 +1,43 @@ +! RUN: bbc %s -o - --strict-fir-volatile-verifier | FileCheck %s + +! Ensure that assignments between volatile classes/derived type pointer/targets +! lower to the correct hlfir declare/designate operations. + +module m + type :: dt + character :: c0="!" + integer :: i=0 + character :: c1="!" + end type + end module + program dataptrvolatile + use m + implicit none + type(dt), volatile , target :: arr(100, 100), arr1(10000), t(100,100) + class(dt), volatile , pointer :: ptr(:, :) + integer :: i, j + do i =1, 100 + do j =i, 100 + arr(i:, j:) = dt(i=-i) + ptr(i:, j:) => arr(i:, j:) + t(i:, j:) = ptr(i:, j:) + end do + end do +end + +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEarr"} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.shape<2>) -> (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEarr1"} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.shape<1>) -> (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "_QFEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "_QFEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEptr"} : (!fir.ref,i:i32,c1:!fir.char<1>}>>>, volatile>, volatile>) -> (!fir.ref,i:i32,c1:!fir.char<1>}>>>, volatile>, volatile>, !fir.ref,i:i32,c1:!fir.char<1>}>>>, volatile>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEt"} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.shape<2>) -> (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, !fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "ctor.temp"} : (!fir.ref,i:i32,c1:!fir.char<1>}>>) -> (!fir.ref,i:i32,c1:!fir.char<1>}>>, !fir.ref,i:i32,c1:!fir.char<1>}>>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"c0"} typeparams %{{.+}} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, index) -> !fir.ref> +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QQclX21"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"i"} : (!fir.ref,i:i32,c1:!fir.char<1>}>>) -> !fir.ref +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"c1"} typeparams %{{.+}} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, index) -> !fir.ref> +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QQclX21"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box,i:i32,c1:!fir.char<1>}>>, volatile> +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box,i:i32,c1:!fir.char<1>}>>, volatile> +! CHECK: %{{.+}} = hlfir.designate %{{.+}} (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.class,i:i32,c1:!fir.char<1>}>>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.class,i:i32,c1:!fir.char<1>}>>, volatile> +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}:%{{.+}}:%{{.+}}, %{{.+}}:%{{.+}}:%{{.+}}) shape %{{.+}} : (!fir.ref,i:i32,c1:!fir.char<1>}>>, volatile>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box,i:i32,c1:!fir.char<1>}>>, volatile>