Skip to content

Commit 7796d81

Browse files
committed
[flang] Skip Fortran STOP: before message when NO_STOP_MESSAGE is set
In 'STOP bye bye', do not print 'Fortran STOP:` before 'bye bye' when NO_STOP_MESSAGE environment variable is set at runtime. Also only exit with code 1 in StopStatementText if this is an ERROR STOP. This matches other compiler behaviors. Move STOP related unit tests in their own test file and add new tests to cover this change. Differential Revision: https://reviews.llvm.org/D114152
1 parent 180625f commit 7796d81

File tree

4 files changed

+97
-22
lines changed

4 files changed

+97
-22
lines changed

flang/runtime/stop.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,19 @@ static void CloseAllExternalUnits(const char *why) {
7171
const char *code, std::size_t length, bool isErrorStop, bool quiet) {
7272
CloseAllExternalUnits("STOP statement");
7373
if (!quiet) {
74-
std::fprintf(stderr, "Fortran %s: %.*s\n",
75-
isErrorStop ? "ERROR STOP" : "STOP", static_cast<int>(length), code);
74+
if (Fortran::runtime::executionEnvironment.noStopMessage && !isErrorStop) {
75+
std::fprintf(stderr, "%.*s\n", static_cast<int>(length), code);
76+
} else {
77+
std::fprintf(stderr, "Fortran %s: %.*s\n",
78+
isErrorStop ? "ERROR STOP" : "STOP", static_cast<int>(length), code);
79+
}
7680
DescribeIEEESignaledExceptions();
7781
}
78-
std::exit(EXIT_FAILURE);
82+
if (isErrorStop) {
83+
std::exit(EXIT_FAILURE);
84+
} else {
85+
std::exit(EXIT_SUCCESS);
86+
}
7987
}
8088

8189
static bool StartPause() {

flang/unittests/Runtime/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add_flang_unittest(FlangRuntimeTests
1414
Random.cpp
1515
Reduction.cpp
1616
RuntimeCrashTest.cpp
17+
Stop.cpp
1718
Time.cpp
1819
Transformational.cpp
1920
)

flang/unittests/Runtime/RuntimeCrashTest.cpp

-19
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "CrashHandlerFixture.h"
1414
#include "../../runtime/terminator.h"
1515
#include "flang/Runtime/io-api.h"
16-
#include "flang/Runtime/stop.h"
1716
#include <gtest/gtest.h>
1817

1918
using namespace Fortran::runtime;
@@ -156,21 +155,3 @@ TEST(TestIOCrash, OverwriteBufferIntegerTest) {
156155
ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xdeadbeef),
157156
"Internal write overran available records");
158157
}
159-
160-
TEST(TestIOCrash, StopTest) {
161-
EXPECT_EXIT(RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS),
162-
"Fortran STOP");
163-
}
164-
165-
TEST(TestIOCrash, FailImageTest) {
166-
EXPECT_EXIT(
167-
RTNAME(FailImageStatement)(), testing::ExitedWithCode(EXIT_FAILURE), "");
168-
}
169-
170-
TEST(TestIOCrash, ExitTest) {
171-
EXPECT_EXIT(RTNAME(Exit)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
172-
EXPECT_EXIT(
173-
RTNAME(Exit)(EXIT_FAILURE), testing::ExitedWithCode(EXIT_FAILURE), "");
174-
}
175-
176-
TEST(TestIOCrash, AbortTest) { EXPECT_DEATH(RTNAME(Abort)(), ""); }

flang/unittests/Runtime/Stop.cpp

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//===-- flang/unittests/Runtime/Stop.cpp ----------------------------------===//
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+
/// Test runtime API for STOP statement and runtime API to kill the program.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
#include "flang/Runtime/stop.h"
13+
#include "CrashHandlerFixture.h"
14+
#include "../../runtime/environment.h"
15+
#include <cstdlib>
16+
#include <gtest/gtest.h>
17+
18+
using namespace Fortran::runtime;
19+
20+
struct TestProgramEnd : CrashHandlerFixture {};
21+
22+
TEST(TestProgramEnd, StopTest) {
23+
EXPECT_EXIT(RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS),
24+
"Fortran STOP");
25+
}
26+
27+
TEST(TestProgramEnd, StopTestNoStopMessage) {
28+
putenv(const_cast<char *>("NO_STOP_MESSAGE=1"));
29+
Fortran::runtime::executionEnvironment.Configure(0, nullptr, nullptr);
30+
EXPECT_EXIT(
31+
RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
32+
}
33+
34+
TEST(TestProgramEnd, StopMessageTest) {
35+
static const char *message{"bye bye"};
36+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
37+
/*isErrorStop=*/false, /*quiet=*/false),
38+
testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
39+
40+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
41+
/*isErrorStop=*/false, /*quiet=*/true),
42+
testing::ExitedWithCode(EXIT_SUCCESS), "");
43+
44+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
45+
/*isErrorStop=*/true, /*quiet=*/false),
46+
testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
47+
48+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
49+
/*isErrorStop=*/true, /*quiet=*/true),
50+
testing::ExitedWithCode(EXIT_FAILURE), "");
51+
}
52+
53+
TEST(TestProgramEnd, NoStopMessageTest) {
54+
putenv(const_cast<char *>("NO_STOP_MESSAGE=1"));
55+
Fortran::runtime::executionEnvironment.Configure(0, nullptr, nullptr);
56+
static const char *message{"bye bye"};
57+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
58+
/*isErrorStop=*/false, /*quiet=*/false),
59+
testing::ExitedWithCode(EXIT_SUCCESS), "bye bye");
60+
61+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
62+
/*isErrorStop=*/false, /*quiet=*/true),
63+
testing::ExitedWithCode(EXIT_SUCCESS), "");
64+
65+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
66+
/*isErrorStop=*/true, /*quiet=*/false),
67+
testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
68+
69+
EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
70+
/*isErrorStop=*/true, /*quiet=*/true),
71+
testing::ExitedWithCode(EXIT_FAILURE), "");
72+
}
73+
74+
TEST(TestProgramEnd, FailImageTest) {
75+
EXPECT_EXIT(
76+
RTNAME(FailImageStatement)(), testing::ExitedWithCode(EXIT_FAILURE), "");
77+
}
78+
79+
TEST(TestProgramEnd, ExitTest) {
80+
EXPECT_EXIT(RTNAME(Exit)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
81+
EXPECT_EXIT(
82+
RTNAME(Exit)(EXIT_FAILURE), testing::ExitedWithCode(EXIT_FAILURE), "");
83+
}
84+
85+
TEST(TestProgramEnd, AbortTest) { EXPECT_DEATH(RTNAME(Abort)(), ""); }

0 commit comments

Comments
 (0)