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