1 //===-- flang/unittests/Runtime/Pointer.cpp--------- -------------*- C++-*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "flang/Runtime/pointer.h"
10 #include "gtest/gtest.h"
12 #include "flang/Runtime/descriptor.h"
14 using namespace Fortran::runtime
;
16 TEST(Pointer
, BasicAllocateDeallocate
) {
17 // REAL(4), POINTER :: p(:)
18 auto p
{Descriptor::Create(TypeCode
{Fortran::common::TypeCategory::Real
, 4}, 4,
19 nullptr, 1, nullptr, CFI_attribute_pointer
)};
21 RTNAME(PointerSetBounds
)(*p
, 0, 2, 11);
22 RTNAME(PointerAllocate
)
23 (*p
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
24 EXPECT_TRUE(RTNAME(PointerIsAssociated
)(*p
));
25 EXPECT_EQ(p
->Elements(), 10u);
26 EXPECT_EQ(p
->GetDimension(0).LowerBound(), 2);
27 EXPECT_EQ(p
->GetDimension(0).UpperBound(), 11);
29 RTNAME(PointerDeallocate
)
30 (*p
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
31 EXPECT_FALSE(RTNAME(PointerIsAssociated
)(*p
));
34 TEST(Pointer
, ApplyMoldAllocation
) {
35 // REAL(4), POINTER :: p
36 auto m
{Descriptor::Create(TypeCode
{Fortran::common::TypeCategory::Real
, 4}, 4,
37 nullptr, 0, nullptr, CFI_attribute_pointer
)};
38 RTNAME(PointerAllocate
)
39 (*m
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
41 // CLASS(*), POINTER :: p
42 auto p
{Descriptor::Create(TypeCode
{Fortran::common::TypeCategory::Real
, 4}, 4,
43 nullptr, 0, nullptr, CFI_attribute_pointer
)};
44 p
->raw().elem_len
= 0;
45 p
->raw().type
= CFI_type_other
;
47 RTNAME(PointerApplyMold
)(*p
, *m
);
48 RTNAME(PointerAllocate
)
49 (*p
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
51 EXPECT_EQ(p
->ElementBytes(), m
->ElementBytes());
52 EXPECT_EQ(p
->type(), m
->type());
55 TEST(Pointer
, DeallocatePolymorphic
) {
57 // ALLOCATE(integer::p)
58 auto p
{Descriptor::Create(TypeCode
{Fortran::common::TypeCategory::Integer
, 4},
59 4, nullptr, 0, nullptr, CFI_attribute_pointer
)};
60 RTNAME(PointerAllocate
)
61 (*p
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
63 RTNAME(PointerDeallocatePolymorphic
)
64 (*p
, nullptr, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
67 TEST(Pointer
, AllocateFromScalarSource
) {
68 // REAL(4), POINTER :: p(:)
69 auto p
{Descriptor::Create(TypeCode
{Fortran::common::TypeCategory::Real
, 4}, 4,
70 nullptr, 1, nullptr, CFI_attribute_pointer
)};
71 // ALLOCATE(p(2:11), SOURCE=3.4)
72 float sourecStorage
{3.4F
};
73 auto s
{Descriptor::Create(Fortran::common::TypeCategory::Real
, 4,
74 reinterpret_cast<void *>(&sourecStorage
), 0, nullptr,
75 CFI_attribute_pointer
)};
76 RTNAME(PointerSetBounds
)(*p
, 0, 2, 11);
77 RTNAME(PointerAllocateSource
)
78 (*p
, *s
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
79 EXPECT_TRUE(RTNAME(PointerIsAssociated
)(*p
));
80 EXPECT_EQ(p
->Elements(), 10u);
81 EXPECT_EQ(p
->GetDimension(0).LowerBound(), 2);
82 EXPECT_EQ(p
->GetDimension(0).UpperBound(), 11);
83 EXPECT_EQ(*p
->OffsetElement
<float>(), 3.4F
);
87 TEST(Pointer
, AllocateSourceZeroSize
) {
88 using Fortran::common::TypeCategory
;
89 // REAL(4), POINTER :: p(:)
90 auto p
{Descriptor::Create(TypeCode
{Fortran::common::TypeCategory::Real
, 4}, 4,
91 nullptr, 1, nullptr, CFI_attribute_pointer
)};
92 // REAL(4) :: s(-1:-2) = 0.
93 float sourecStorage
{0.F
};
94 const SubscriptValue extents
[1]{0};
95 auto s
{Descriptor::Create(TypeCategory::Real
, 4,
96 reinterpret_cast<void *>(&sourecStorage
), 1, extents
,
97 CFI_attribute_other
)};
98 // ALLOCATE(p, SOURCE=s)
99 RTNAME(PointerSetBounds
)(*p
, 0, -1, -2);
100 RTNAME(PointerAllocateSource
)
101 (*p
, *s
, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__
, __LINE__
);
102 EXPECT_TRUE(RTNAME(PointerIsAssociated
)(*p
));
103 EXPECT_EQ(p
->Elements(), 0u);
104 EXPECT_EQ(p
->GetDimension(0).LowerBound(), 1);
105 EXPECT_EQ(p
->GetDimension(0).UpperBound(), 0);