diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -4117,13 +4117,13 @@ return builder.create(loc, dimIsEmpty, one, lb); } -/// Create a fir.box to be passed to the LBOUND runtime. +/// Create a fir.box to be passed to the LBOUND/UBOUND runtime. /// This ensure that local lower bounds of assumed shape are propagated and that /// a fir.box with equivalent LBOUNDs but an explicit shape is created for /// assumed size arrays to avoid undefined behaviors in codegen or the runtime. -static mlir::Value createBoxForLBOUND(mlir::Location loc, - fir::FirOpBuilder &builder, - const fir::ExtendedValue &array) { +static mlir::Value +createBoxForRuntimeBoundInquiry(mlir::Location loc, fir::FirOpBuilder &builder, + const fir::ExtendedValue &array) { if (!array.isAssumedSize()) return array.match( [&](const fir::BoxValue &boxValue) -> mlir::Value { @@ -4217,7 +4217,7 @@ return builder.createConvert(loc, resultType, lb); } - fir::ExtendedValue box = createBoxForLBOUND(loc, builder, array); + fir::ExtendedValue box = createBoxForRuntimeBoundInquiry(loc, builder, array); return builder.createConvert( loc, resultType, fir::runtime::genLboundDim(builder, loc, fir::getBase(box), dim)); @@ -4251,8 +4251,9 @@ mlir::Value resultIrBox = fir::factory::getMutableIRBox(builder, loc, resultMutableBox); - fir::runtime::genUbound(builder, loc, resultIrBox, fir::getBase(args[0]), - kind); + fir::ExtendedValue box = + createBoxForRuntimeBoundInquiry(loc, builder, args[0]); + fir::runtime::genUbound(builder, loc, resultIrBox, fir::getBase(box), kind); return readAndAddCleanUp(resultMutableBox, resultType, "UBOUND"); } diff --git a/flang/test/Lower/Intrinsics/ubound01.f90 b/flang/test/Lower/Intrinsics/ubound01.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Lower/Intrinsics/ubound01.f90 @@ -0,0 +1,23 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s + +! Check that assumed shape lower bounds are applied before passing the +! descriptor to the runtime call. + + real, target :: a(10:20,99:100) + call s2(a,17,-100) +contains + subroutine show(bounds) + integer(8) :: bounds(:) + print *, bounds + end subroutine + subroutine s2(a,n,n2) + Real a(n:,n2:) + call show(ubound(a, kind=8)) + End Subroutine +end + +! CHECK-LABEL: func.func @_QFPs2 +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> +! CHECK: %[[BOX:.*]] = fir.rebox %[[ARG0]](%{{.*}}) : (!fir.box>, !fir.shift<2>) -> !fir.box> +! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]] : (!fir.box>) -> !fir.box +! CHECK: %{{.*}} = fir.call @_FortranAUbound(%{{.*}}, %[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i32, !fir.ref, i32) -> none