1 | //===-- unittests/Runtime/Support.cpp ---------------------------*- C++ -*-===// |
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/support.h" |
10 | #include "tools.h" |
11 | #include "gtest/gtest.h" |
12 | #include "flang-rt/runtime/descriptor.h" |
13 | |
14 | using namespace Fortran::runtime; |
15 | using Fortran::common::TypeCategory; |
16 | TEST(CopyAndUpdateDescriptor, Basic) { |
17 | auto x{MakeArray<TypeCategory::Integer, 4>( |
18 | std::vector<int>{2, 3}, std::vector<std::int32_t>{0, 1, 2, 3, 4, 5})}; |
19 | x->GetDimension(0).SetLowerBound(11); |
20 | x->GetDimension(1).SetLowerBound(12); |
21 | |
22 | StaticDescriptor<2, false> statDesc; |
23 | Descriptor &result{statDesc.descriptor()}; |
24 | |
25 | RTNAME(CopyAndUpdateDescriptor) |
26 | (result, *x, nullptr, CFI_attribute_pointer, LowerBoundModifier::Preserve); |
27 | ASSERT_EQ(result.rank(), 2); |
28 | EXPECT_EQ(result.raw().base_addr, x->raw().base_addr); |
29 | EXPECT_TRUE(result.IsPointer()); |
30 | EXPECT_EQ(result.GetDimension(0).Extent(), x->GetDimension(0).Extent()); |
31 | EXPECT_EQ( |
32 | result.GetDimension(0).LowerBound(), x->GetDimension(0).LowerBound()); |
33 | EXPECT_EQ(result.GetDimension(1).Extent(), x->GetDimension(1).Extent()); |
34 | EXPECT_EQ( |
35 | result.GetDimension(1).LowerBound(), x->GetDimension(1).LowerBound()); |
36 | |
37 | RTNAME(CopyAndUpdateDescriptor) |
38 | (result, *x, nullptr, CFI_attribute_allocatable, |
39 | LowerBoundModifier::SetToZeroes); |
40 | ASSERT_EQ(result.rank(), 2); |
41 | EXPECT_EQ(result.raw().base_addr, x->raw().base_addr); |
42 | EXPECT_TRUE(result.IsAllocatable()); |
43 | EXPECT_EQ(result.GetDimension(0).Extent(), x->GetDimension(0).Extent()); |
44 | EXPECT_EQ(result.GetDimension(0).LowerBound(), 0); |
45 | EXPECT_EQ(result.GetDimension(1).Extent(), x->GetDimension(1).Extent()); |
46 | EXPECT_EQ(result.GetDimension(1).LowerBound(), 0); |
47 | |
48 | RTNAME(CopyAndUpdateDescriptor) |
49 | (result, *x, nullptr, CFI_attribute_other, LowerBoundModifier::SetToOnes); |
50 | ASSERT_EQ(result.rank(), 2); |
51 | EXPECT_EQ(result.raw().base_addr, x->raw().base_addr); |
52 | EXPECT_FALSE(result.IsAllocatable()); |
53 | EXPECT_FALSE(result.IsPointer()); |
54 | EXPECT_EQ(result.GetDimension(0).Extent(), x->GetDimension(0).Extent()); |
55 | EXPECT_EQ(result.GetDimension(0).LowerBound(), 1); |
56 | EXPECT_EQ(result.GetDimension(1).Extent(), x->GetDimension(1).Extent()); |
57 | EXPECT_EQ(result.GetDimension(1).LowerBound(), 1); |
58 | } |
59 | |
60 | TEST(IsAssumedSize, Basic) { |
61 | auto x{MakeArray<TypeCategory::Integer, 4>( |
62 | std::vector<int>{2, 3}, std::vector<std::int32_t>{0, 1, 2, 3, 4, 5})}; |
63 | EXPECT_FALSE(RTNAME(IsAssumedSize)(*x)); |
64 | x->GetDimension(1).SetExtent(-1); |
65 | EXPECT_TRUE(RTNAME(IsAssumedSize)(*x)); |
66 | auto scalar{MakeArray<TypeCategory::Integer, 4>( |
67 | std::vector<int>{}, std::vector<std::int32_t>{0})}; |
68 | EXPECT_FALSE(RTNAME(IsAssumedSize)(*scalar)); |
69 | } |
70 | |
71 | TEST(DescriptorBytesFor, Basic) { |
72 | for (size_t i = 0; i < Fortran::common::TypeCategory_enumSize; ++i) { |
73 | auto tc{static_cast<TypeCategory>(i)}; |
74 | if (tc == TypeCategory::Derived) |
75 | continue; |
76 | |
77 | auto b{Descriptor::BytesFor(tc, 4)}; |
78 | EXPECT_GT(b, 0U); |
79 | } |
80 | } |
81 | |
82 | TEST(IsContiguous, Basic) { |
83 | // ARRAY 1 3 5 |
84 | // 2 4 6 |
85 | auto array{MakeArray<TypeCategory::Integer, 4>( |
86 | std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})}; |
87 | StaticDescriptor<2> sectionStaticDesc; |
88 | Descriptor §ion{sectionStaticDesc.descriptor()}; |
89 | section.Establish(array->type(), array->ElementBytes(), |
90 | /*p=*/nullptr, /*rank=*/2); |
91 | static const SubscriptValue lbs[]{1, 1}, ubs[]{2, 3}, strides[]{1, 2}; |
92 | const auto error{ |
93 | CFI_section(§ion.raw(), &array->raw(), lbs, ubs, strides)}; |
94 | ASSERT_EQ(error, 0) << "CFI_section failed for array: " << error; |
95 | |
96 | EXPECT_TRUE(RTNAME(IsContiguous)(*array)); |
97 | EXPECT_FALSE(RTNAME(IsContiguous)(section)); |
98 | EXPECT_TRUE(RTNAME(IsContiguousUpTo)(section, 1)); |
99 | EXPECT_FALSE(RTNAME(IsContiguousUpTo)(section, 2)); |
100 | } |
101 | |