1 //===-- flang/unittests/Runtime/Inquiry.cpp -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "flang/Runtime/inquiry.h"
10 #include "gtest/gtest.h"
11 #include "tools.h"
12 #include "flang/Runtime/type-code.h"
13 
14 using namespace Fortran::runtime;
15 using Fortran::common::TypeCategory;
16 
TEST(Inquiry,Lbound)17 TEST(Inquiry, Lbound) {
18   // ARRAY  1 3 5
19   //        2 4 6
20   auto array{MakeArray<TypeCategory::Integer, 4>(
21       std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
22   array->GetDimension(0).SetLowerBound(0);
23   array->GetDimension(1).SetLowerBound(-1);
24 
25   EXPECT_EQ(RTNAME(LboundDim)(*array, 1, __FILE__, __LINE__), std::int64_t{0});
26   EXPECT_EQ(RTNAME(LboundDim)(*array, 2, __FILE__, __LINE__), std::int64_t{-1});
27 }
28 
TEST(Inquiry,Ubound)29 TEST(Inquiry, Ubound) {
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(1000);
35   array->GetDimension(1).SetLowerBound(1);
36   StaticDescriptor<2, true> statDesc;
37 
38   int intValue{1};
39   SubscriptValue extent[]{2};
40   Descriptor &result{statDesc.descriptor()};
41   result.Establish(TypeCategory::Integer, /*KIND=*/4,
42       static_cast<void *>(&intValue), 1, extent, CFI_attribute_pointer);
43   RTNAME(Ubound)(result, *array, /*KIND=*/4, __FILE__, __LINE__);
44   EXPECT_EQ(result.rank(), 1);
45   EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Integer, 4}.raw()));
46   // The lower bound of UBOUND's result array is always 1
47   EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
48   EXPECT_EQ(result.GetDimension(0).Extent(), 2);
49   EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int32_t>(0), 1001);
50   EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int32_t>(1), 3);
51   result.Destroy();
52 
53   result = statDesc.descriptor();
54   result.Establish(TypeCategory::Integer, /*KIND=*/1,
55       static_cast<void *>(&intValue), 1, extent, CFI_attribute_pointer);
56   RTNAME(Ubound)(result, *array, /*KIND=*/1, __FILE__, __LINE__);
57   EXPECT_EQ(result.rank(), 1);
58   EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Integer, 1}.raw()));
59   // The lower bound of UBOUND's result array is always 1
60   EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
61   EXPECT_EQ(result.GetDimension(0).Extent(), 2);
62   EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int8_t>(0), -23);
63   EXPECT_EQ(*result.ZeroBasedIndexedElement<std::int8_t>(1), 3);
64   result.Destroy();
65 }
66 
TEST(Inquiry,Size)67 TEST(Inquiry, Size) {
68   // ARRAY  1 3 5
69   //        2 4 6
70   auto array{MakeArray<TypeCategory::Integer, 4>(
71       std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
72   array->GetDimension(0).SetLowerBound(0); // shouldn't matter
73   array->GetDimension(1).SetLowerBound(-1);
74 
75   EXPECT_EQ(RTNAME(SizeDim)(*array, 1, __FILE__, __LINE__), std::int64_t{2});
76   EXPECT_EQ(RTNAME(SizeDim)(*array, 2, __FILE__, __LINE__), std::int64_t{3});
77   EXPECT_EQ(RTNAME(Size)(*array, __FILE__, __LINE__), std::int64_t{6});
78 }
79