1 //===-- runtime/stop.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 "stop.h"
10 #include "io-error.h"
11 #include "terminator.h"
12 #include "unit.h"
13 #include <cfenv>
14 #include <cstdio>
15 #include <cstdlib>
16 
17 extern "C" {
18 
19 static void DescribeIEEESignaledExceptions() {
20 #ifdef fetestexcept // a macro in some environments; omit std::
21   auto excepts{fetestexcept(FE_ALL_EXCEPT)};
22 #else
23   auto excepts{std::fetestexcept(FE_ALL_EXCEPT)};
24 #endif
25   if (excepts) {
26     std::fputs("IEEE arithmetic exceptions signaled:", stderr);
27     if (excepts & FE_DIVBYZERO) {
28       std::fputs(" DIVBYZERO", stderr);
29     }
30     if (excepts & FE_INEXACT) {
31       std::fputs(" INEXACT", stderr);
32     }
33     if (excepts & FE_INVALID) {
34       std::fputs(" INVALID", stderr);
35     }
36     if (excepts & FE_OVERFLOW) {
37       std::fputs(" OVERFLOW", stderr);
38     }
39     if (excepts & FE_UNDERFLOW) {
40       std::fputs(" UNDERFLOW", stderr);
41     }
42   }
43 }
44 
45 [[noreturn]] void RTNAME(StopStatement)(
46     int code, bool isErrorStop, bool quiet) {
47   if (!quiet) {
48     if (code != EXIT_SUCCESS) {
49       std::fprintf(stderr, "Fortran %s: code %d\n",
50           isErrorStop ? "ERROR STOP" : "STOP", code);
51     }
52     DescribeIEEESignaledExceptions();
53   }
54   std::exit(code);
55 }
56 
57 [[noreturn]] void RTNAME(StopStatementText)(
58     const char *code, bool isErrorStop, bool quiet) {
59   if (!quiet) {
60     std::fprintf(
61         stderr, "Fortran %s: %s\n", isErrorStop ? "ERROR STOP" : "STOP", code);
62     DescribeIEEESignaledExceptions();
63   }
64   std::exit(EXIT_FAILURE);
65 }
66 
67 [[noreturn]] void RTNAME(FailImageStatement)() {
68   Fortran::runtime::NotifyOtherImagesOfFailImageStatement();
69   std::exit(EXIT_FAILURE);
70 }
71 
72 [[noreturn]] void RTNAME(ProgramEndStatement)() {
73   Fortran::runtime::io::IoErrorHandler handler{"END statement"};
74   Fortran::runtime::io::ExternalFileUnit::CloseAll(handler);
75   std::exit(EXIT_SUCCESS);
76 }
77 }
78