1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "base/base_export.h"
11 #include "base/compiler_specific.h"
12 #include "base/dcheck_is_on.h"
13 #include "base/immediate_crash.h"
15 // This header defines the CHECK, DCHECK, and DPCHECK macros.
17 // CHECK dies with a fatal error if its condition is not true. It is not
18 // controlled by NDEBUG, so the check will be executed regardless of compilation
21 // DCHECK, the "debug mode" check, is enabled depending on NDEBUG and
22 // DCHECK_ALWAYS_ON, and its severity depends on DCHECK_IS_CONFIGURABLE.
24 // (D)PCHECK is like (D)CHECK, but includes the system error code (c.f.
27 // Additional information can be streamed to these macros and will be included
28 // in the log output if the condition doesn't hold (you may need to include
31 // CHECK(condition) << "Additional info.";
33 // The condition is evaluated exactly once. Even in build modes where e.g.
34 // DCHECK is disabled, the condition and any stream arguments are still
35 // referenced to avoid warnings about unused variables and functions.
37 // For the (D)CHECK_EQ, etc. macros, see base/check_op.h. However, that header
38 // is *significantly* larger than check.h, so try to avoid including it in
43 // Class used to explicitly ignore an ostream, and optionally a boolean value.
46 VoidifyStream() = default;
47 explicit VoidifyStream(bool ignored) {}
49 // This operator has lower precedence than << but higher than ?:
50 void operator&(std::ostream&) {}
53 // Helper macro which avoids evaluating the arguents to a stream if the
54 // condition is false.
55 #define LAZY_CHECK_STREAM(stream, condition) \
56 !(condition) ? (void)0 : ::logging::VoidifyStream() & (stream)
58 // Macro which uses but does not evaluate expr and any stream parameters.
59 #define EAT_CHECK_STREAM_PARAMS(expr) \
61 : ::logging::VoidifyStream(expr) & (*::logging::g_swallow_stream)
62 BASE_EXPORT extern std::ostream* g_swallow_stream;
67 // Class used for raising a check error upon destruction.
68 class BASE_EXPORT CheckError {
70 static CheckError Check(const char* file, int line, const char* condition);
71 static CheckError CheckOp(const char* file, int line, CheckOpResult* result);
73 static CheckError DCheck(const char* file, int line, const char* condition);
74 static CheckError DCheckOp(const char* file, int line, CheckOpResult* result);
76 static CheckError PCheck(const char* file, int line, const char* condition);
77 static CheckError PCheck(const char* file, int line);
79 static CheckError DPCheck(const char* file, int line, const char* condition);
81 static CheckError NotImplemented(const char* file,
83 const char* function);
85 // Stream for adding optional details to the error message.
86 std::ostream& stream();
90 CheckError(const CheckError& other) = delete;
91 CheckError& operator=(const CheckError& other) = delete;
92 CheckError(CheckError&& other) = default;
93 CheckError& operator=(CheckError&& other) = default;
96 explicit CheckError(LogMessage* log_message);
98 LogMessage* log_message_;
101 #if defined(OFFICIAL_BUILD) && defined(NDEBUG)
103 // Discard log strings to reduce code bloat.
105 // This is not calling BreakDebugger since this is called frequently, and
106 // calling an out-of-line function instead of a noreturn inline macro prevents
107 // compiler optimizations.
108 #define CHECK(condition) \
109 UNLIKELY(!(condition)) ? IMMEDIATE_CRASH() : EAT_CHECK_STREAM_PARAMS()
111 #define PCHECK(condition) \
113 ::logging::CheckError::PCheck(__FILE__, __LINE__).stream(), \
114 UNLIKELY(!(condition)))
118 #define CHECK(condition) \
120 ::logging::CheckError::Check(__FILE__, __LINE__, #condition).stream(), \
121 !ANALYZER_ASSUME_TRUE(condition))
123 #define PCHECK(condition) \
125 ::logging::CheckError::PCheck(__FILE__, __LINE__, #condition).stream(), \
126 !ANALYZER_ASSUME_TRUE(condition))
132 #define DCHECK(condition) \
134 ::logging::CheckError::DCheck(__FILE__, __LINE__, #condition).stream(), \
135 !ANALYZER_ASSUME_TRUE(condition))
137 #define DPCHECK(condition) \
139 ::logging::CheckError::DPCheck(__FILE__, __LINE__, #condition).stream(), \
140 !ANALYZER_ASSUME_TRUE(condition))
144 #define DCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
145 #define DPCHECK(condition) EAT_CHECK_STREAM_PARAMS(!(condition))
149 // Async signal safe checking mechanism.
150 BASE_EXPORT void RawCheck(const char* message);
151 #define RAW_CHECK(condition) \
154 ::logging::RawCheck("Check failed: " #condition "\n"); \
157 } // namespace logging
159 #endif // BASE_CHECK_H_