//===-- unittests/Runtime/Stop.cpp ------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// Test runtime API for STOP statement and runtime API to kill the program. // //===----------------------------------------------------------------------===// #include "flang/Runtime/stop.h" #include "CrashHandlerFixture.h" #include "flang-rt/runtime/environment.h" #include #include #include using namespace Fortran::runtime; struct TestProgramEnd : CrashHandlerFixture {}; TEST_F(TestProgramEnd, StopTest) { EXPECT_EXIT(RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP"); } TEST_F(TestProgramEnd, StopTestNoStopMessage) { EXPECT_EXIT( { static char noStopMessage[] = "NO_STOP_MESSAGE=1"; putenv(noStopMessage); Fortran::runtime::executionEnvironment.Configure( 0, nullptr, nullptr, nullptr); RTNAME(StopStatement)(); }, testing::ExitedWithCode(EXIT_SUCCESS), ""); } TEST_F(TestProgramEnd, StopMessageTest) { static const char *message{"bye bye"}; EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/false, /*quiet=*/false), testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye"); EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/false, /*quiet=*/true), testing::ExitedWithCode(EXIT_SUCCESS), ""); EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/true, /*quiet=*/false), testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye"); EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/true, /*quiet=*/true), testing::ExitedWithCode(EXIT_FAILURE), ""); } TEST_F(TestProgramEnd, NoStopMessageTest) { static const char *message{"bye bye"}; EXPECT_EXIT( { static char noStopMessage[] = "NO_STOP_MESSAGE=1"; putenv(noStopMessage); Fortran::runtime::executionEnvironment.Configure( 0, nullptr, nullptr, nullptr); RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/false, /*quiet=*/false); }, testing::ExitedWithCode(EXIT_SUCCESS), "bye bye"); EXPECT_EXIT( { static char noStopMessage[] = "NO_STOP_MESSAGE=1"; putenv(noStopMessage); Fortran::runtime::executionEnvironment.Configure( 0, nullptr, nullptr, nullptr); RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/false, /*quiet=*/true); }, testing::ExitedWithCode(EXIT_SUCCESS), ""); EXPECT_EXIT( { static char noStopMessage[] = "NO_STOP_MESSAGE=1"; putenv(noStopMessage); Fortran::runtime::executionEnvironment.Configure( 0, nullptr, nullptr, nullptr); RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/true, /*quiet=*/false); }, testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye"); EXPECT_EXIT( { static char noStopMessage[] = "NO_STOP_MESSAGE=1"; putenv(noStopMessage); Fortran::runtime::executionEnvironment.Configure( 0, nullptr, nullptr, nullptr); RTNAME(StopStatementText)(message, std::strlen(message), /*isErrorStop=*/true, /*quiet=*/true); }, testing::ExitedWithCode(EXIT_FAILURE), ""); } TEST_F(TestProgramEnd, FailImageTest) { EXPECT_EXIT( RTNAME(FailImageStatement)(), testing::ExitedWithCode(EXIT_FAILURE), ""); } TEST_F(TestProgramEnd, ExitTest) { EXPECT_EXIT(RTNAME(Exit)(), testing::ExitedWithCode(EXIT_SUCCESS), ""); EXPECT_EXIT( RTNAME(Exit)(EXIT_FAILURE), testing::ExitedWithCode(EXIT_FAILURE), ""); } TEST_F(TestProgramEnd, AbortTest) { EXPECT_DEATH(RTNAME(Abort)(), ""); } TEST_F(TestProgramEnd, CrashTest) { static const std::string crashMessage{"bad user code"}; static const std::string fileName{"file name"}; // CrashHandlerFixture installs a custom crash handler that formats messages // as: "Test crashed in file (): " static const std::string fullMessage{"Test CrashTest crashed in file " + fileName + "\\(343\\): " + crashMessage}; EXPECT_DEATH( RTNAME(ReportFatalUserError)(crashMessage.c_str(), fileName.c_str(), 343), fullMessage.c_str()); }