xref: /llvm-project/flang/unittests/Runtime/MiscIntrinsic.cpp (revision ffc67bb3602a6a9a4f886af362e1f2d7c9821570)
1 //===-- flang/unittests/Runtime/MiscIntrinsic.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 "gtest/gtest.h"
10 #include "tools.h"
11 #include "flang/Runtime/misc-intrinsic.h"
12 #include "flang/Runtime/allocatable.h"
13 #include "flang/Runtime/cpp-type.h"
14 #include "flang/Runtime/descriptor.h"
15 
16 using namespace Fortran::runtime;
17 
18 // TRANSFER examples from Fortran 2018
19 
TEST(MiscIntrinsic,TransferScalar)20 TEST(MiscIntrinsic, TransferScalar) {
21   StaticDescriptor<2, true, 2> staticDesc[2];
22   auto &result{staticDesc[0].descriptor()};
23   auto source{MakeArray<TypeCategory::Integer, 4>(
24       std::vector<int>{}, std::vector<std::int32_t>{1082130432})};
25   auto &mold{staticDesc[1].descriptor()};
26   mold.Establish(TypeCategory::Real, 4, nullptr, 0);
27   RTNAME(Transfer)(result, *source, mold, __FILE__, __LINE__);
28   EXPECT_EQ(result.rank(), 0);
29   EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Real, 4}.raw()));
30   EXPECT_EQ(*result.OffsetElement<float>(), 4.0);
31   result.Destroy();
32 }
33 
TEST(MiscIntrinsic,TransferMold)34 TEST(MiscIntrinsic, TransferMold) {
35   StaticDescriptor<2, true, 2> staticDesc[2];
36   auto &result{staticDesc[0].descriptor()};
37   auto source{MakeArray<TypeCategory::Real, 4>(
38       std::vector<int>{3}, std::vector<float>{1.1F, 2.2F, 3.3F})};
39   auto &mold{staticDesc[1].descriptor()};
40   SubscriptValue extent[1]{1};
41   mold.Establish(TypeCategory::Complex, 4, nullptr, 1, extent);
42   RTNAME(Transfer)(result, *source, mold, __FILE__, __LINE__);
43   EXPECT_EQ(result.rank(), 1);
44   EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
45   EXPECT_EQ(result.GetDimension(0).Extent(), 2);
46   EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Complex, 4}.raw()));
47   EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
48   EXPECT_EQ(result.OffsetElement<float>()[1], 2.2F);
49   EXPECT_EQ(result.OffsetElement<float>()[2], 3.3F);
50   EXPECT_EQ(result.OffsetElement<float>()[3], 0.0F);
51   result.Destroy();
52 }
53 
TEST(MiscIntrinsic,TransferSize)54 TEST(MiscIntrinsic, TransferSize) {
55   StaticDescriptor<2, true, 2> staticDesc[2];
56   auto &result{staticDesc[0].descriptor()};
57   auto source{MakeArray<TypeCategory::Real, 4>(
58       std::vector<int>{3}, std::vector<float>{1.1F, 2.2F, 3.3F})};
59   auto &mold{staticDesc[1].descriptor()};
60   SubscriptValue extent[1]{1};
61   mold.Establish(TypeCategory::Complex, 4, nullptr, 1, extent);
62   RTNAME(TransferSize)(result, *source, mold, __FILE__, __LINE__, 1);
63   EXPECT_EQ(result.rank(), 1);
64   EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
65   EXPECT_EQ(result.GetDimension(0).Extent(), 1);
66   EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Complex, 4}.raw()));
67   EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
68   EXPECT_EQ(result.OffsetElement<float>()[1], 2.2F);
69   result.Destroy();
70 }
TEST(MiscIntrinsic,TransferSizeScalarMold)71 TEST(MiscIntrinsic, TransferSizeScalarMold) {
72   StaticDescriptor<2, true, 2> staticDesc[2];
73   auto &result{staticDesc[0].descriptor()};
74   std::complex<float> sourecStorage{1.1F, -2.2F};
75   auto source{Descriptor::Create(TypeCategory::Complex, 4,
76       reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
77       CFI_attribute_pointer)};
78   auto &mold{staticDesc[1].descriptor()};
79   mold.Establish(TypeCategory::Real, 4, nullptr, 0, nullptr);
80   RTNAME(TransferSize)(result, *source, mold, __FILE__, __LINE__, 2);
81   EXPECT_EQ(result.rank(), 1);
82   EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
83   EXPECT_EQ(result.GetDimension(0).Extent(), 2);
84   EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Real, 4}.raw()));
85   EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
86   EXPECT_EQ(result.OffsetElement<float>()[1], -2.2F);
87   result.Destroy();
88 }
89