|
|
@@ -31,7 +31,9 @@ CheckCondition(bool condition)
|
|
|
// Implements the check failure message printing.
|
|
|
//
|
|
|
// This is out-of-line and will arrange to stop the program, print any debugging
|
|
|
-// information and this string.
|
|
|
+// information and this string. In `!NDEBUG` mode (`dbg` and `fastbuild`), check
|
|
|
+// failures can be made non-fatal by a build flag, so this is not `[[noreturn]]`
|
|
|
+// in that case.
|
|
|
//
|
|
|
// This API uses `const char*` C string arguments rather than `llvm::StringRef`
|
|
|
// because we know that these are available as C strings and passing them that
|
|
|
@@ -39,9 +41,12 @@ CheckCondition(bool condition)
|
|
|
// a single pointer argument for each. The runtime cost of re-computing the size
|
|
|
// should be minimal. The extra message however might not be compile-time
|
|
|
// guaranteed to be a C string so we use a normal `StringRef` there.
|
|
|
-[[noreturn]] auto CheckFailImpl(const char* kind, const char* file, int line,
|
|
|
- const char* condition_str,
|
|
|
- llvm::StringRef extra_message) -> void;
|
|
|
+#ifdef NDEBUG
|
|
|
+[[noreturn]]
|
|
|
+#endif
|
|
|
+auto CheckFailImpl(const char* kind, const char* file, int line,
|
|
|
+ const char* condition_str, llvm::StringRef extra_message)
|
|
|
+ -> void;
|
|
|
|
|
|
// Allow converting format values; the default behaviour is to just pass them
|
|
|
// through.
|
|
|
@@ -77,8 +82,11 @@ auto ConvertFormatValue(T&& t) {
|
|
|
// `llvm::formatv` which handles all of the formatting of output.
|
|
|
template <TemplateString Kind, TemplateString File, int Line,
|
|
|
TemplateString ConditionStr, TemplateString FormatStr, typename... Ts>
|
|
|
-[[noreturn, gnu::cold, clang::noinline]] auto CheckFail(Ts&&... values)
|
|
|
- -> void {
|
|
|
+#ifdef NDEBUG
|
|
|
+[[noreturn]]
|
|
|
+#endif
|
|
|
+[[gnu::cold, clang::noinline]] auto
|
|
|
+CheckFail(Ts&&... values) -> void {
|
|
|
if constexpr (llvm::StringRef(FormatStr).empty()) {
|
|
|
// Skip the format string rendering if empty. Note that we don't skip it
|
|
|
// even if there are no values as we want to have consistent handling of
|
|
|
@@ -135,9 +143,10 @@ template <TemplateString Kind, TemplateString File, int Line,
|
|
|
//
|
|
|
// Similar to the check failure macro, but tags the message as a fatal one and
|
|
|
// leaves the stringified condition empty.
|
|
|
-#define CARBON_INTERNAL_FATAL(...) \
|
|
|
- CARBON_INTERNAL_CHECK_IMPL##__VA_OPT__(_FORMAT)( \
|
|
|
- "FATAL", __FILE__, __LINE__, "" __VA_OPT__(, ) __VA_ARGS__)
|
|
|
+#define CARBON_INTERNAL_FATAL(...) \
|
|
|
+ (CARBON_INTERNAL_CHECK_IMPL##__VA_OPT__(_FORMAT)( \
|
|
|
+ "FATAL", __FILE__, __LINE__, "" __VA_OPT__(, ) __VA_ARGS__), \
|
|
|
+ CARBON_INTERNAL_FATAL_NORETURN_SUFFIX())
|
|
|
|
|
|
#ifdef NDEBUG
|
|
|
// For `DCHECK` in optimized builds we have a dead check that we want to
|
|
|
@@ -153,6 +162,11 @@ template <TemplateString Kind, TemplateString File, int Line,
|
|
|
|
|
|
#define CARBON_INTERNAL_DEAD_DCHECK_IMPL_FORMAT(format_str, ...) \
|
|
|
Carbon::Internal::CheckFail<"", "", 0, "", "">(__VA_ARGS__)
|
|
|
+
|
|
|
+// The CheckFail function itself is noreturn in NDEBUG.
|
|
|
+#define CARBON_INTERNAL_FATAL_NORETURN_SUFFIX() void()
|
|
|
+#else
|
|
|
+#define CARBON_INTERNAL_FATAL_NORETURN_SUFFIX() std::abort()
|
|
|
#endif
|
|
|
|
|
|
#endif // CARBON_COMMON_CHECK_INTERNAL_H_
|