Skip to content

Commit a0faf79

Browse files
authored
[flang][runtime] add LBOUND API for assumed-rank arrays (#94808)
1 parent 760d880 commit a0faf79

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

flang/include/flang/Runtime/inquiry.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ extern "C" {
2424
std::int64_t RTDECL(LboundDim)(const Descriptor &array, int dim,
2525
const char *sourceFile = nullptr, int line = 0);
2626

27-
void RTDECL(Shape)(void *result, const Descriptor &array, int kind,
27+
void RTDECL(Lbound)(void *result, const Descriptor &array, int kind,
2828
const char *sourceFile = nullptr, int line = 0);
2929

30+
void RTDECL(Shape)(void *result, const Descriptor &array, int kind,
31+
const char *sourceFile = nullptr, int line = 0);
3032
std::int64_t RTDECL(Size)(
3133
const Descriptor &array, const char *sourceFile = nullptr, int line = 0);
3234

flang/runtime/inquiry.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,16 @@ void RTDEF(Shape)(void *result, const Descriptor &array, int kind,
9696
}
9797
}
9898

99+
void RTDEF(Lbound)(void *result, const Descriptor &array, int kind,
100+
const char *sourceFile, int line) {
101+
Terminator terminator{sourceFile, line};
102+
INTERNAL_CHECK(array.rank() <= common::maxRank);
103+
for (SubscriptValue i{0}; i < array.rank(); ++i) {
104+
const Dimension &dimension{array.GetDimension(i)};
105+
Fortran::runtime::ApplyIntegerKind<RawStoreIntegerAt, void>(
106+
kind, terminator, result, i, dimension.LowerBound());
107+
}
108+
}
109+
99110
} // extern "C"
100111
} // namespace Fortran::runtime

flang/unittests/Runtime/Inquiry.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
using namespace Fortran::runtime;
1515
using Fortran::common::TypeCategory;
1616

17-
TEST(Inquiry, Lbound) {
17+
TEST(Inquiry, LboundDim) {
1818
// ARRAY 1 3 5
1919
// 2 4 6
2020
auto array{MakeArray<TypeCategory::Integer, 4>(
@@ -26,6 +26,42 @@ TEST(Inquiry, Lbound) {
2626
EXPECT_EQ(RTNAME(LboundDim)(*array, 2, __FILE__, __LINE__), std::int64_t{-1});
2727
}
2828

29+
TEST(Inquiry, Lbound) {
30+
// ARRAY 1 3 5
31+
// 2 4 6
32+
auto array{MakeArray<TypeCategory::Integer, 4>(
33+
std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
34+
array->GetDimension(0).SetLowerBound(0);
35+
array->GetDimension(1).SetLowerBound(-1);
36+
37+
// LBOUND(ARRAY, KIND=1)
38+
auto int8Result{
39+
MakeArray<TypeCategory::Integer, 1>(std::vector<int>{array->rank()},
40+
std::vector<std::int8_t>(array->rank(), 0))};
41+
RTNAME(Lbound)
42+
(int8Result->raw().base_addr, *array, /*KIND=*/1, __FILE__, __LINE__);
43+
EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(0), 0);
44+
EXPECT_EQ(*int8Result->ZeroBasedIndexedElement<std::int8_t>(1), -1);
45+
46+
// LBOUND(ARRAY, KIND=4)
47+
auto int32Result{
48+
MakeArray<TypeCategory::Integer, 4>(std::vector<int>{array->rank()},
49+
std::vector<std::int32_t>(array->rank(), 0))};
50+
RTNAME(Lbound)
51+
(int32Result->raw().base_addr, *array, /*KIND=*/4, __FILE__, __LINE__);
52+
EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(0), 0);
53+
EXPECT_EQ(*int32Result->ZeroBasedIndexedElement<std::int32_t>(1), -1);
54+
55+
// LBOUND(ARRAY, KIND=8)
56+
auto int64Result{
57+
MakeArray<TypeCategory::Integer, 8>(std::vector<int>{array->rank()},
58+
std::vector<std::int64_t>(array->rank(), 0))};
59+
RTNAME(Lbound)
60+
(int64Result->raw().base_addr, *array, /*KIND=*/8, __FILE__, __LINE__);
61+
EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(0), 0);
62+
EXPECT_EQ(*int64Result->ZeroBasedIndexedElement<std::int64_t>(1), -1);
63+
}
64+
2965
TEST(Inquiry, Ubound) {
3066
// ARRAY 1 3 5
3167
// 2 4 6

0 commit comments

Comments
 (0)