[flang][cuda] Adapt ExternalNameConversion to work in gpu module (#117039)
[llvm-project.git] / flang / unittests / Runtime / RuntimeCrashTest.cpp
bloba649051fdca0c5b2ec55af5fe02c3228eddaa7c1
1 //===-- flang/unittests/Runtime/CrashHandlerFixture.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 /// Selected APIs are tested here to support development of unit tests for other
10 /// runtime components and ensure the test fixture handles crashes as we expect.
12 //===----------------------------------------------------------------------===//
13 #include "CrashHandlerFixture.h"
14 #include "tools.h"
15 #include "../../runtime/terminator.h"
16 #include "flang/Runtime/io-api.h"
17 #include "flang/Runtime/transformational.h"
18 #include <gtest/gtest.h>
20 using namespace Fortran::runtime;
21 using namespace Fortran::runtime::io;
22 using Fortran::common::TypeCategory;
24 //------------------------------------------------------------------------------
25 /// Test crashes through direct calls to terminator methods
26 //------------------------------------------------------------------------------
27 struct TestTerminator : CrashHandlerFixture {};
29 #define TEST_CRASH_HANDLER_MESSAGE \
30 "Intentionally crashing runtime for unit test"
32 TEST(TestTerminator, CrashTest) {
33 static Fortran::runtime::Terminator t;
34 ASSERT_DEATH(t.Crash(TEST_CRASH_HANDLER_MESSAGE), TEST_CRASH_HANDLER_MESSAGE);
37 #undef TEST_CRASH_HANDLER_MESSAGE
39 TEST(TestTerminator, CheckFailedLocationTest) {
40 static Fortran::runtime::Terminator t;
41 ASSERT_DEATH(t.CheckFailed("predicate", "someFileName", 789),
42 "RUNTIME_CHECK\\(predicate\\) failed at someFileName\\(789\\)");
45 TEST(TestTerminator, CheckFailedTest) {
46 static Fortran::runtime::Terminator t("someFileName");
47 ASSERT_DEATH(t.CheckFailed("predicate"),
48 "RUNTIME_CHECK\\(predicate\\) failed at someFileName\\(0\\)");
51 //------------------------------------------------------------------------------
52 /// Test misuse of io api
53 //------------------------------------------------------------------------------
54 struct TestIOCrash : CrashHandlerFixture {};
56 TEST(TestIOCrash, InvalidFormatCharacterTest) {
57 static constexpr int bufferSize{1};
58 static char buffer[bufferSize];
59 static const char *format{"(C1)"};
60 auto *cookie{IONAME(BeginInternalFormattedOutput)(
61 buffer, bufferSize, format, std::strlen(format))};
62 ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xfeedface),
63 "Unknown 'C' edit descriptor in FORMAT");
66 //------------------------------------------------------------------------------
67 /// Test buffer overwrites with Output* functions
68 /// Each test performs the tested IO operation correctly first, before causing
69 /// an overwrite to demonstrate that the failure is caused by the overwrite and
70 /// not a misuse of the API.
71 //------------------------------------------------------------------------------
72 TEST(TestIOCrash, OverwriteBufferAsciiTest) {
73 static constexpr int bufferSize{4};
74 static char buffer[bufferSize];
75 static const char *format{"(A4)"};
76 auto *cookie{IONAME(BeginInternalFormattedOutput)(
77 buffer, bufferSize, format, std::strlen(format))};
78 IONAME(OutputAscii)(cookie, "four", bufferSize);
79 ASSERT_DEATH(IONAME(OutputAscii)(cookie, "Too many characters!", 20),
80 "Internal write overran available records");
83 TEST(TestIOCrash, OverwriteBufferCharacterTest) {
84 static constexpr int bufferSize{1};
85 static char buffer[bufferSize];
86 static const char *format{"(A1)"};
87 auto *cookie{IONAME(BeginInternalFormattedOutput)(
88 buffer, bufferSize, format, std::strlen(format))};
89 IONAME(OutputCharacter)(cookie, "a", 1);
90 ASSERT_DEATH(IONAME(OutputCharacter)(cookie, "a", 1),
91 "Internal write overran available records");
94 TEST(TestIOCrash, OverwriteBufferLogicalTest) {
95 static constexpr int bufferSize{1};
96 static char buffer[bufferSize];
97 static const char *format{"(L1)"};
98 auto *cookie{IONAME(BeginInternalFormattedOutput)(
99 buffer, bufferSize, format, std::strlen(format))};
100 IONAME(OutputLogical)(cookie, true);
101 ASSERT_DEATH(IONAME(OutputLogical)(cookie, true),
102 "Internal write overran available records");
105 TEST(TestIOCrash, OverwriteBufferRealTest) {
106 static constexpr int bufferSize{1};
107 static char buffer[bufferSize];
108 static const char *format{"(F1)"};
109 auto *cookie{IONAME(BeginInternalFormattedOutput)(
110 buffer, bufferSize, format, std::strlen(format))};
111 IONAME(OutputReal32)(cookie, 1.);
112 EXPECT_DEATH(IONAME(OutputReal32)(cookie, 1.),
113 "Internal write overran available records");
115 std::memset(buffer, '\0', bufferSize);
116 cookie = IONAME(BeginInternalFormattedOutput)(
117 buffer, bufferSize, format, std::strlen(format));
118 IONAME(OutputReal64)(cookie, 1.);
119 EXPECT_DEATH(IONAME(OutputReal64)(cookie, 1.),
120 "Internal write overran available records");
123 TEST(TestIOCrash, OverwriteBufferComplexTest) {
124 static constexpr int bufferSize{8};
125 static char buffer[bufferSize];
126 static const char *format{"(Z1,Z1)"};
127 auto *cookie{IONAME(BeginInternalFormattedOutput)(
128 buffer, bufferSize, format, std::strlen(format))};
129 IONAME(OutputComplex32)(cookie, 1., 1.);
130 EXPECT_DEATH(IONAME(OutputComplex32)(cookie, 1., 1.),
131 "Internal write overran available records");
133 std::memset(buffer, '\0', bufferSize);
134 cookie = IONAME(BeginInternalFormattedOutput)(
135 buffer, bufferSize, format, std::strlen(format));
136 IONAME(OutputComplex64)(cookie, 1., 1.);
137 EXPECT_DEATH(IONAME(OutputComplex64)(cookie, 1., 1.),
138 "Internal write overran available records");
141 TEST(TestIOCrash, OverwriteBufferIntegerTest) {
142 static constexpr int bufferSize{1};
143 static char buffer[bufferSize];
144 static const char *format{"(I1)"};
145 auto *cookie{IONAME(BeginInternalFormattedOutput)(
146 buffer, bufferSize, format, std::strlen(format))};
147 IONAME(OutputInteger64)(cookie, 0xdeadbeef);
148 ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xdeadbeef),
149 "Internal write overran available records");
152 //------------------------------------------------------------------------------
153 /// Test conformity issue reports in transformational intrinsics
154 //------------------------------------------------------------------------------
155 struct TestIntrinsicCrash : CrashHandlerFixture {};
157 TEST(TestIntrinsicCrash, ConformityErrors) {
158 // ARRAY(2,3) and MASK(2,4) should trigger a runtime error.
159 auto array{MakeArray<TypeCategory::Integer, 4>(
160 std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
161 auto mask{MakeArray<TypeCategory::Logical, 1>(std::vector<int>{2, 4},
162 std::vector<std::uint8_t>{
163 false, true, true, false, false, true, true, true})};
164 StaticDescriptor<1, true> statDesc;
165 Descriptor &result{statDesc.descriptor()};
167 ASSERT_DEATH(RTNAME(Pack)(result, *array, *mask, nullptr, __FILE__, __LINE__),
168 "Incompatible array arguments to PACK: dimension 2 of ARRAY= has extent "
169 "3 but MASK= has extent 4");