1 | //===-- flang/unittests/Runtime/Pointer.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/pointer.h" |
10 | #include "gtest/gtest.h" |
11 | #include "tools.h" |
12 | #include "flang/Runtime/descriptor.h" |
13 | |
14 | using namespace Fortran::runtime; |
15 | |
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)}; |
20 | // ALLOCATE(p(2:11)) |
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); |
28 | // DEALLOCATE(p) |
29 | RTNAME(PointerDeallocate) |
30 | (*p, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); |
31 | EXPECT_FALSE(RTNAME(PointerIsAssociated)(*p)); |
32 | } |
33 | |
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__); |
40 | |
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; |
46 | |
47 | RTNAME(PointerApplyMold)(*p, *m); |
48 | RTNAME(PointerAllocate) |
49 | (*p, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); |
50 | |
51 | EXPECT_EQ(p->ElementBytes(), m->ElementBytes()); |
52 | EXPECT_EQ(p->type(), m->type()); |
53 | } |
54 | |
55 | TEST(Pointer, DeallocatePolymorphic) { |
56 | // CLASS(*) :: p |
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__); |
62 | // DEALLOCATE(p) |
63 | RTNAME(PointerDeallocatePolymorphic) |
64 | (*p, nullptr, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); |
65 | } |
66 | |
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); |
84 | p->Destroy(); |
85 | } |
86 | |
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); |
106 | p->Destroy(); |
107 | } |
108 | |