xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/ErrorHandling.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- 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 // This file defines an API used to indicate fatal error conditions.  Non-fatal
10 // errors (most of them) should be handled through LLVMContext.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_SUPPORT_ERRORHANDLING_H
15 #define LLVM_SUPPORT_ERRORHANDLING_H
16 
17 #include "llvm/Support/Compiler.h"
18 
19 namespace llvm {
20 class StringRef;
21 class Twine;
22 
23 /// An error handler callback.
24 typedef void (*fatal_error_handler_t)(void *user_data, const char *reason,
25                                       bool gen_crash_diag);
26 
27 /// install_fatal_error_handler - Installs a new error handler to be used
28 /// whenever a serious (non-recoverable) error is encountered by LLVM.
29 ///
30 /// If no error handler is installed the default is to print the error message
31 /// to stderr, and call exit(1).  If an error handler is installed then it is
32 /// the handler's responsibility to log the message, it will no longer be
33 /// printed to stderr.  If the error handler returns, then exit(1) will be
34 /// called.
35 ///
36 /// It is dangerous to naively use an error handler which throws an exception.
37 /// Even though some applications desire to gracefully recover from arbitrary
38 /// faults, blindly throwing exceptions through unfamiliar code isn't a way to
39 /// achieve this.
40 ///
41 /// \param user_data - An argument which will be passed to the install error
42 /// handler.
43 LLVM_ABI void install_fatal_error_handler(fatal_error_handler_t handler,
44                                           void *user_data = nullptr);
45 
46 /// Restores default error handling behaviour.
47 LLVM_ABI void remove_fatal_error_handler();
48 
49 /// ScopedFatalErrorHandler - This is a simple helper class which just
50 /// calls install_fatal_error_handler in its constructor and
51 /// remove_fatal_error_handler in its destructor.
52 struct ScopedFatalErrorHandler {
53   explicit ScopedFatalErrorHandler(fatal_error_handler_t handler,
54                                    void *user_data = nullptr) {
55     install_fatal_error_handler(handler, user_data);
56   }
57 
~ScopedFatalErrorHandlerScopedFatalErrorHandler58   ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); }
59 };
60 
61 /// @deprecated Use reportFatalInternalError() or reportFatalUsageError()
62 /// instead.
63 [[noreturn]] LLVM_ABI void report_fatal_error(const char *reason,
64                                               bool gen_crash_diag = true);
65 [[noreturn]] LLVM_ABI void report_fatal_error(StringRef reason,
66                                               bool gen_crash_diag = true);
67 [[noreturn]] LLVM_ABI void report_fatal_error(const Twine &reason,
68                                               bool gen_crash_diag = true);
69 
70 /// Report a fatal error that likely indicates a bug in LLVM. It serves a
71 /// similar purpose as an assertion, but is always enabled, regardless of the
72 /// value of NDEBUG.
73 ///
74 /// This will call installed error handlers (or print the message by default)
75 /// and then abort. This will produce a crash trace and *will* ask users to
76 /// report an LLVM bug.
77 [[noreturn]] LLVM_ABI void reportFatalInternalError(const char *reason);
78 [[noreturn]] LLVM_ABI void reportFatalInternalError(StringRef reason);
79 [[noreturn]] LLVM_ABI void reportFatalInternalError(const Twine &reason);
80 
81 /// Report a fatal error that does not indicate a bug in LLVM.
82 ///
83 /// This can be used in contexts where a proper error reporting mechanism
84 /// (such as Error/Expected or DiagnosticInfo) is currently not supported, and
85 /// would be too involved to introduce at the moment.
86 ///
87 /// Examples where this function should be used instead of
88 /// reportFatalInternalError() include invalid inputs or options, but also
89 /// environment error conditions outside LLVM's control. It should also be used
90 /// for known unsupported/unimplemented functionality.
91 ///
92 /// This will call installed error handlers (or print the message by default)
93 /// and then exit with code 1. It will not produce a crash trace and will
94 /// *not* ask users to report an LLVM bug.
95 [[noreturn]] LLVM_ABI void reportFatalUsageError(const char *reason);
96 [[noreturn]] LLVM_ABI void reportFatalUsageError(StringRef reason);
97 [[noreturn]] LLVM_ABI void reportFatalUsageError(const Twine &reason);
98 
99 /// Installs a new bad alloc error handler that should be used whenever a
100 /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM.
101 ///
102 /// The user can install a bad alloc handler, in order to define the behavior
103 /// in case of failing allocations, e.g. throwing an exception. Note that this
104 /// handler must not trigger any additional allocations itself.
105 ///
106 /// If no error handler is installed the default is to print the error message
107 /// to stderr, and call exit(1).  If an error handler is installed then it is
108 /// the handler's responsibility to log the message, it will no longer be
109 /// printed to stderr.  If the error handler returns, then exit(1) will be
110 /// called.
111 ///
112 ///
113 /// \param user_data - An argument which will be passed to the installed error
114 /// handler.
115 LLVM_ABI void install_bad_alloc_error_handler(fatal_error_handler_t handler,
116                                               void *user_data = nullptr);
117 
118 /// Restores default bad alloc error handling behavior.
119 LLVM_ABI void remove_bad_alloc_error_handler();
120 
121 LLVM_ABI void install_out_of_memory_new_handler();
122 
123 /// Reports a bad alloc error, calling any user defined bad alloc
124 /// error handler. In contrast to the generic 'report_fatal_error'
125 /// functions, this function might not terminate, e.g. the user
126 /// defined error handler throws an exception, but it won't return.
127 ///
128 /// Note: When throwing an exception in the bad alloc handler, make sure that
129 /// the following unwind succeeds, e.g. do not trigger additional allocations
130 /// in the unwind chain.
131 ///
132 /// If no error handler is installed (default), throws a bad_alloc exception
133 /// if LLVM is compiled with exception support. Otherwise prints the error
134 /// to standard error and calls abort().
135 [[noreturn]] LLVM_ABI void report_bad_alloc_error(const char *Reason,
136                                                   bool GenCrashDiag = true);
137 
138 /// This function calls abort(), and prints the optional message to stderr.
139 /// Use the llvm_unreachable macro (that adds location info), instead of
140 /// calling this function directly.
141 [[noreturn]] LLVM_ABI void llvm_unreachable_internal(const char *msg = nullptr,
142                                                      const char *file = nullptr,
143                                                      unsigned line = 0);
144 } // namespace llvm
145 
146 /// Marks that the current location is not supposed to be reachable.
147 /// In !NDEBUG builds, prints the message and location info to stderr.
148 /// In NDEBUG builds, if the platform does not support a builtin unreachable
149 /// then we call an internal LLVM runtime function. Otherwise the behavior is
150 /// controlled by the CMake flag
151 ///   -DLLVM_UNREACHABLE_OPTIMIZE
152 /// * When "ON" (default) llvm_unreachable() becomes an optimizer hint
153 ///   that the current location is not supposed to be reachable: the hint
154 ///   turns such code path into undefined behavior.  On compilers that don't
155 ///   support such hints, prints a reduced message instead and aborts the
156 ///   program.
157 /// * When "OFF", a builtin_trap is emitted instead of an
158 //    optimizer hint or printing a reduced message.
159 ///
160 /// Use this instead of assert(0). It conveys intent more clearly, suppresses
161 /// diagnostics for unreachable code paths, and allows compilers to omit
162 /// unnecessary code.
163 #ifndef NDEBUG
164 #define llvm_unreachable(msg)                                                  \
165   ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
166 #elif !defined(LLVM_BUILTIN_UNREACHABLE)
167 #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
168 #elif LLVM_UNREACHABLE_OPTIMIZE
169 #define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
170 #else
171 #define llvm_unreachable(msg)                                                  \
172   do {                                                                         \
173     LLVM_BUILTIN_TRAP;                                                         \
174     LLVM_BUILTIN_UNREACHABLE;                                                  \
175   } while (false)
176 #endif
177 
178 #endif
179