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
14using namespace Fortran::runtime;
15using Fortran::common::TypeCategory;
16TEST(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
60TEST(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
71TEST(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
82TEST(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 &section{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(&section.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

source code of flang-rt/unittests/Runtime/Support.cpp