diff --git a/flang/include/flang/Runtime/stop.h b/flang/include/flang/Runtime/stop.h --- a/flang/include/flang/Runtime/stop.h +++ b/flang/include/flang/Runtime/stop.h @@ -30,6 +30,10 @@ NORETURN void RTNAME(Exit)(int status = EXIT_SUCCESS); NORETURN void RTNAME(Abort)(NO_ARGUMENTS); +// Crash with an error message when the program dynamically violates a Fortran +// constraint. +NORETURN void RTNAME(Crash)(const char *message, const char *source, int line); + FORTRAN_EXTERN_C_END #endif // FORTRAN_RUNTIME_STOP_H_ diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp --- a/flang/runtime/stop.cpp +++ b/flang/runtime/stop.cpp @@ -143,4 +143,9 @@ } [[noreturn]] void RTNAME(Abort)() { std::abort(); } + +[[noreturn]] void RTNAME(Crash)( + const char *message, const char *source, int line) { + Fortran::runtime::Terminator{source, line}.Crash(message); +} } diff --git a/flang/unittests/Runtime/Stop.cpp b/flang/unittests/Runtime/Stop.cpp --- a/flang/unittests/Runtime/Stop.cpp +++ b/flang/unittests/Runtime/Stop.cpp @@ -83,3 +83,14 @@ } TEST(TestProgramEnd, AbortTest) { EXPECT_DEATH(RTNAME(Abort)(), ""); } + +TEST(TestProgramEnd, CrashTest) { + static const std::string crashMessage{"bad user code"}; + static const std::string fileName{"file name"}; + static const std::string headMessage{"fatal Fortran runtime error\\("}; + static const std::string tailMessage{":343\\): "}; + static const std::string fullMessage{ + headMessage + fileName + tailMessage + crashMessage}; + EXPECT_DEATH(RTNAME(Crash)(crashMessage.c_str(), fileName.c_str(), 343), + fullMessage.c_str()); +}