• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- runtime/terminate.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 "terminator.h"
10 #include <cstdio>
11 #include <cstdlib>
12 
13 namespace Fortran::runtime {
14 
Crash(const char * message,...) const15 [[noreturn]] void Terminator::Crash(const char *message, ...) const {
16   va_list ap;
17   va_start(ap, message);
18   CrashArgs(message, ap);
19 }
20 
21 static void (*crashHandler)(const char *, int, const char *, va_list &){
22     nullptr};
23 
RegisterCrashHandler(void (* handler)(const char *,int,const char *,va_list &))24 void Terminator::RegisterCrashHandler(
25     void (*handler)(const char *, int, const char *, va_list &)) {
26   crashHandler = handler;
27 }
28 
CrashArgs(const char * message,va_list & ap) const29 [[noreturn]] void Terminator::CrashArgs(
30     const char *message, va_list &ap) const {
31   if (crashHandler) {
32     crashHandler(sourceFileName_, sourceLine_, message, ap);
33   }
34   std::fputs("\nfatal Fortran runtime error", stderr);
35   if (sourceFileName_) {
36     std::fprintf(stderr, "(%s", sourceFileName_);
37     if (sourceLine_) {
38       std::fprintf(stderr, ":%d", sourceLine_);
39     }
40     fputc(')', stderr);
41   }
42   std::fputs(": ", stderr);
43   std::vfprintf(stderr, message, ap);
44   fputc('\n', stderr);
45   va_end(ap);
46   io::FlushOutputOnCrash(*this);
47   NotifyOtherImagesOfErrorTermination();
48   std::abort();
49 }
50 
CheckFailed(const char * predicate,const char * file,int line) const51 [[noreturn]] void Terminator::CheckFailed(
52     const char *predicate, const char *file, int line) const {
53   Crash("Internal error: RUNTIME_CHECK(%s) failed at %s(%d)", predicate, file,
54       line);
55 }
56 
CheckFailed(const char * predicate) const57 [[noreturn]] void Terminator::CheckFailed(const char *predicate) const {
58   Crash("Internal error: RUNTIME_CHECK(%s) failed at %s(%d)", predicate,
59       sourceFileName_, sourceLine_);
60 }
61 
62 // TODO: These will be defined in the coarray runtime library
NotifyOtherImagesOfNormalEnd()63 void NotifyOtherImagesOfNormalEnd() {}
NotifyOtherImagesOfFailImageStatement()64 void NotifyOtherImagesOfFailImageStatement() {}
NotifyOtherImagesOfErrorTermination()65 void NotifyOtherImagesOfErrorTermination() {}
66 } // namespace Fortran::runtime
67