1 // Copyright 2022 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // -----------------------------------------------------------------------------
16 // File: log/internal/check_op.h
17 // -----------------------------------------------------------------------------
18 //
19 // This file declares helpers routines and macros used to implement `CHECK`
20 // macros.
21 
22 #ifndef ABSL_LOG_INTERNAL_CHECK_OP_H_
23 #define ABSL_LOG_INTERNAL_CHECK_OP_H_
24 
25 #include <stdint.h>
26 
27 #include <ostream>
28 #include <sstream>
29 #include <string>
30 #include <utility>
31 
32 #include "absl/base/attributes.h"
33 #include "absl/base/config.h"
34 #include "absl/base/optimization.h"
35 #include "absl/log/internal/nullguard.h"
36 #include "absl/log/internal/nullstream.h"
37 #include "absl/log/internal/strip.h"
38 
39 // `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
40 // should be stripped when `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`.
41 #ifdef ABSL_MIN_LOG_LEVEL
42 #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal)         \
43   (::absl::LogSeverity::kFatal >=                               \
44            static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
45        ? (literal)                                              \
46        : "")
47 #else
48 #define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) (literal)
49 #endif
50 
51 #ifdef NDEBUG
52 // `NDEBUG` is defined, so `DCHECK_EQ(x, y)` and so on do nothing.  However, we
53 // still want the compiler to parse `x` and `y`, because we don't want to lose
54 // potentially useful errors and warnings.
55 #define ABSL_LOG_INTERNAL_DCHECK_NOP(x, y)   \
56   while (false && ((void)(x), (void)(y), 0)) \
57   ::absl::log_internal::NullStream().InternalStream()
58 #endif
59 
60 #define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \
61   while (                                                                      \
62       ::std::string* absl_log_internal_check_op_result ABSL_ATTRIBUTE_UNUSED = \
63           ::absl::log_internal::name##Impl(                                    \
64               ::absl::log_internal::GetReferenceableValue(val1),               \
65               ::absl::log_internal::GetReferenceableValue(val2),               \
66               ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val1_text                 \
67                                                      " " #op " " val2_text)))  \
68   ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_op_result).InternalStream()
69 #define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
70                                     val2_text)                       \
71   while (::std::string* absl_log_internal_qcheck_op_result =         \
72              ::absl::log_internal::name##Impl(                       \
73                  ::absl::log_internal::GetReferenceableValue(val1),  \
74                  ::absl::log_internal::GetReferenceableValue(val2),  \
75                  ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(             \
76                      val1_text " " #op " " val2_text)))              \
77   ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_op_result).InternalStream()
78 #define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2,     \
79                                       s2_text)                                 \
80   while (::std::string* absl_log_internal_check_strop_result =                 \
81              ::absl::log_internal::Check##func##expected##Impl(                \
82                  (s1), (s2),                                                   \
83                  ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op        \
84                                                                 " " s2_text))) \
85   ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_strop_result)               \
86       .InternalStream()
87 #define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2,    \
88                                        s2_text)                                \
89   while (::std::string* absl_log_internal_qcheck_strop_result =                \
90              ::absl::log_internal::Check##func##expected##Impl(                \
91                  (s1), (s2),                                                   \
92                  ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op        \
93                                                                 " " s2_text))) \
94   ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_qcheck_strop_result)             \
95       .InternalStream()
96 // This one is tricky:
97 // * We must evaluate `val` exactly once, yet we need to do two things with it:
98 //   evaluate `.ok()` and (sometimes) `.ToString()`.
99 // * `val` might be an `absl::Status` or some `absl::StatusOr<T>`.
100 // * `val` might be e.g. `ATemporary().GetStatus()`, which may return a
101 //   reference to a member of `ATemporary` that is only valid until the end of
102 //   the full expression.
103 // * We don't want this file to depend on `absl::Status` `#include`s or linkage,
104 //   nor do we want to move the definition to status and introduce a dependency
105 //   in the other direction.  We can be assured that callers must already have a
106 //   `Status` and the necessary `#include`s and linkage.
107 // * Callsites should be small and fast (at least when `val.ok()`): one branch,
108 //   minimal stack footprint.
109 //   * In particular, the string concat stuff should be out-of-line and emitted
110 //     in only one TU to save linker input size
111 // * We want the `val.ok()` check inline so static analyzers and optimizers can
112 //   see it.
113 // * As usual, no braces so we can stream into the expansion with `operator<<`.
114 // * Also as usual, it must expand to a single (partial) statement with no
115 //   ambiguous-else problems.
116 #define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text)                        \
117   for (::std::pair<const ::absl::Status*, ::std::string*>                \
118            absl_log_internal_check_ok_goo;                               \
119        absl_log_internal_check_ok_goo.first =                            \
120            ::absl::log_internal::AsStatus(val),                          \
121        absl_log_internal_check_ok_goo.second =                           \
122            ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
123                ? nullptr                                                 \
124                : ::absl::status_internal::MakeCheckFailString(           \
125                      absl_log_internal_check_ok_goo.first,               \
126                      ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text     \
127                                                             " is OK")),  \
128        !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());)  \
129   ABSL_LOG_INTERNAL_CHECK(*absl_log_internal_check_ok_goo.second)        \
130       .InternalStream()
131 #define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text)                       \
132   for (::std::pair<const ::absl::Status*, ::std::string*>                \
133            absl_log_internal_check_ok_goo;                               \
134        absl_log_internal_check_ok_goo.first =                            \
135            ::absl::log_internal::AsStatus(val),                          \
136        absl_log_internal_check_ok_goo.second =                           \
137            ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
138                ? nullptr                                                 \
139                : ::absl::status_internal::MakeCheckFailString(           \
140                      absl_log_internal_check_ok_goo.first,               \
141                      ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text     \
142                                                             " is OK")),  \
143        !ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());)  \
144   ABSL_LOG_INTERNAL_QCHECK(*absl_log_internal_check_ok_goo.second)       \
145       .InternalStream()
146 
147 namespace absl {
148 ABSL_NAMESPACE_BEGIN
149 
150 class Status;
151 template <typename T>
152 class StatusOr;
153 
154 namespace status_internal {
155 std::string* MakeCheckFailString(const absl::Status* status,
156                                  const char* prefix);
157 }  // namespace status_internal
158 
159 namespace log_internal {
160 
161 // Convert a Status or a StatusOr to its underlying status value.
162 //
163 // (This implementation does not require a dep on absl::Status to work.)
AsStatus(const absl::Status & s)164 inline const absl::Status* AsStatus(const absl::Status& s) { return &s; }
165 template <typename T>
AsStatus(const absl::StatusOr<T> & s)166 const absl::Status* AsStatus(const absl::StatusOr<T>& s) {
167   return &s.status();
168 }
169 
170 // A helper class for formatting `expr (V1 vs. V2)` in a `CHECK_XX` statement.
171 // See `MakeCheckOpString` for sample usage.
172 class CheckOpMessageBuilder final {
173  public:
174   // Inserts `exprtext` and ` (` to the stream.
175   explicit CheckOpMessageBuilder(const char* exprtext);
176   ~CheckOpMessageBuilder() = default;
177   // For inserting the first variable.
ForVar1()178   std::ostream& ForVar1() { return stream_; }
179   // For inserting the second variable (adds an intermediate ` vs. `).
180   std::ostream& ForVar2();
181   // Get the result (inserts the closing `)`).
182   std::string* NewString();
183 
184  private:
185   std::ostringstream stream_;
186 };
187 
188 // This formats a value for a failing `CHECK_XX` statement.  Ordinarily, it uses
189 // the definition for `operator<<`, with a few special cases below.
190 template <typename T>
MakeCheckOpValueString(std::ostream & os,const T & v)191 inline void MakeCheckOpValueString(std::ostream& os, const T& v) {
192   os << log_internal::NullGuard<T>::Guard(v);
193 }
194 
195 // Overloads for char types provide readable values for unprintable characters.
196 void MakeCheckOpValueString(std::ostream& os, char v);
197 void MakeCheckOpValueString(std::ostream& os, signed char v);
198 void MakeCheckOpValueString(std::ostream& os, unsigned char v);
199 void MakeCheckOpValueString(std::ostream& os, const void* p);
200 
201 namespace detect_specialization {
202 
203 // MakeCheckOpString is being specialized for every T and U pair that is being
204 // passed to the CHECK_op macros. However, there is a lot of redundancy in these
205 // specializations that creates unnecessary library and binary bloat.
206 // The number of instantiations tends to be O(n^2) because we have two
207 // independent inputs. This technique works by reducing `n`.
208 //
209 // Most user-defined types being passed to CHECK_op end up being printed as a
210 // builtin type. For example, enums tend to be implicitly converted to its
211 // underlying type when calling operator<<, and pointers are printed with the
212 // `const void*` overload.
213 // To reduce the number of instantiations we coerce these values before calling
214 // MakeCheckOpString instead of inside it.
215 //
216 // To detect if this coercion is needed, we duplicate all the relevant
217 // operator<< overloads as specified in the standard, just in a different
218 // namespace. If the call to `stream << value` becomes ambiguous, it means that
219 // one of these overloads is the one selected by overload resolution. We then
220 // do overload resolution again just with our overload set to see which one gets
221 // selected. That tells us which type to coerce to.
222 // If the augmented call was not ambiguous, it means that none of these were
223 // selected and we can't coerce the input.
224 //
225 // As a secondary step to reduce code duplication, we promote integral types to
226 // their 64-bit variant. This does not change the printed value, but reduces the
227 // number of instantiations even further. Promoting an integer is very cheap at
228 // the call site.
229 int64_t operator<<(std::ostream&, short value);           // NOLINT
230 int64_t operator<<(std::ostream&, unsigned short value);  // NOLINT
231 int64_t operator<<(std::ostream&, int value);
232 int64_t operator<<(std::ostream&, unsigned int value);
233 int64_t operator<<(std::ostream&, long value);                 // NOLINT
234 uint64_t operator<<(std::ostream&, unsigned long value);       // NOLINT
235 int64_t operator<<(std::ostream&, long long value);            // NOLINT
236 uint64_t operator<<(std::ostream&, unsigned long long value);  // NOLINT
237 float operator<<(std::ostream&, float value);
238 double operator<<(std::ostream&, double value);
239 long double operator<<(std::ostream&, long double value);
240 bool operator<<(std::ostream&, bool value);
241 const void* operator<<(std::ostream&, const void* value);
242 const void* operator<<(std::ostream&, std::nullptr_t);
243 
244 // These `char` overloads are specified like this in the standard, so we have to
245 // write them exactly the same to ensure the call is ambiguous.
246 // If we wrote it in a different way (eg taking std::ostream instead of the
247 // template) then one call might have a higher rank than the other and it would
248 // not be ambiguous.
249 template <typename Traits>
250 char operator<<(std::basic_ostream<char, Traits>&, char);
251 template <typename Traits>
252 signed char operator<<(std::basic_ostream<char, Traits>&, signed char);
253 template <typename Traits>
254 unsigned char operator<<(std::basic_ostream<char, Traits>&, unsigned char);
255 template <typename Traits>
256 const char* operator<<(std::basic_ostream<char, Traits>&, const char*);
257 template <typename Traits>
258 const signed char* operator<<(std::basic_ostream<char, Traits>&,
259                               const signed char*);
260 template <typename Traits>
261 const unsigned char* operator<<(std::basic_ostream<char, Traits>&,
262                                 const unsigned char*);
263 
264 // This overload triggers when the call is not ambiguous.
265 // It means that T is being printed with some overload not on this list.
266 // We keep the value as `const T&`.
267 template <typename T, typename = decltype(std::declval<std::ostream&>()
268                                           << std::declval<const T&>())>
269 const T& Detect(int);
270 
271 // This overload triggers when the call is ambiguous.
272 // It means that T is either one from this list or printed as one from this
273 // list. Eg an enum that decays to `int` for printing.
274 // We ask the overload set to give us the type we want to convert it to.
275 template <typename T>
276 decltype(detect_specialization::operator<<(std::declval<std::ostream&>(),
277                                            std::declval<const T&>()))
278 Detect(char);
279 
280 }  // namespace detect_specialization
281 
282 template <typename T>
283 using CheckOpStreamType = decltype(detect_specialization::Detect<T>(0));
284 
285 // Build the error message string.  Specify no inlining for code size.
286 template <typename T1, typename T2>
287 ABSL_ATTRIBUTE_RETURNS_NONNULL std::string* MakeCheckOpString(
288     T1 v1, T2 v2, const char* exprtext) ABSL_ATTRIBUTE_NOINLINE;
289 
290 template <typename T1, typename T2>
MakeCheckOpString(T1 v1,T2 v2,const char * exprtext)291 std::string* MakeCheckOpString(T1 v1, T2 v2, const char* exprtext) {
292   CheckOpMessageBuilder comb(exprtext);
293   MakeCheckOpValueString(comb.ForVar1(), v1);
294   MakeCheckOpValueString(comb.ForVar2(), v2);
295   return comb.NewString();
296 }
297 
298 // Add a few commonly used instantiations as extern to reduce size of objects
299 // files.
300 #define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \
301   extern template std::string* MakeCheckOpString(x, x, const char*)
302 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool);
303 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t);
304 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t);
305 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(float);
306 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(double);
307 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(char);
308 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(unsigned char);
309 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const std::string&);
310 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const absl::string_view&);
311 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const char*);
312 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const signed char*);
313 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const unsigned char*);
314 ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
315 #undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN
316 
317 // Helper functions for `ABSL_LOG_INTERNAL_CHECK_OP` macro family.  The
318 // `(int, int)` override works around the issue that the compiler will not
319 // instantiate the template version of the function on values of unnamed enum
320 // type.
321 #define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op)                        \
322   template <typename T1, typename T2>                                    \
323   inline constexpr ::std::string* name##Impl(const T1& v1, const T2& v2, \
324                                              const char* exprtext) {     \
325     using U1 = CheckOpStreamType<T1>;                                    \
326     using U2 = CheckOpStreamType<T2>;                                    \
327     return ABSL_PREDICT_TRUE(v1 op v2)                                   \
328                ? nullptr                                                 \
329                : MakeCheckOpString<U1, U2>(v1, v2, exprtext);            \
330   }                                                                      \
331   inline constexpr ::std::string* name##Impl(int v1, int v2,             \
332                                              const char* exprtext) {     \
333     return name##Impl<int, int>(v1, v2, exprtext);                       \
334   }
335 
336 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_EQ, ==)
337 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_NE, !=)
338 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LE, <=)
339 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LT, <)
340 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GE, >=)
341 ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GT, >)
342 #undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL
343 
344 std::string* CheckstrcmptrueImpl(const char* s1, const char* s2,
345                                  const char* exprtext);
346 std::string* CheckstrcmpfalseImpl(const char* s1, const char* s2,
347                                   const char* exprtext);
348 std::string* CheckstrcasecmptrueImpl(const char* s1, const char* s2,
349                                      const char* exprtext);
350 std::string* CheckstrcasecmpfalseImpl(const char* s1, const char* s2,
351                                       const char* exprtext);
352 
353 // `CHECK_EQ` and friends want to pass their arguments by reference, however
354 // this winds up exposing lots of cases where people have defined and
355 // initialized static const data members but never declared them (i.e. in a .cc
356 // file), meaning they are not referenceable.  This function avoids that problem
357 // for integers (the most common cases) by overloading for every primitive
358 // integer type, even the ones we discourage, and returning them by value.
359 template <typename T>
GetReferenceableValue(const T & t)360 inline constexpr const T& GetReferenceableValue(const T& t) {
361   return t;
362 }
GetReferenceableValue(char t)363 inline constexpr char GetReferenceableValue(char t) { return t; }
GetReferenceableValue(unsigned char t)364 inline constexpr unsigned char GetReferenceableValue(unsigned char t) {
365   return t;
366 }
GetReferenceableValue(signed char t)367 inline constexpr signed char GetReferenceableValue(signed char t) { return t; }
GetReferenceableValue(short t)368 inline constexpr short GetReferenceableValue(short t) { return t; }  // NOLINT
GetReferenceableValue(unsigned short t)369 inline constexpr unsigned short GetReferenceableValue(               // NOLINT
370     unsigned short t) {                                              // NOLINT
371   return t;
372 }
GetReferenceableValue(int t)373 inline constexpr int GetReferenceableValue(int t) { return t; }
GetReferenceableValue(unsigned int t)374 inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
GetReferenceableValue(long t)375 inline constexpr long GetReferenceableValue(long t) { return t; }  // NOLINT
GetReferenceableValue(unsigned long t)376 inline constexpr unsigned long GetReferenceableValue(              // NOLINT
377     unsigned long t) {                                             // NOLINT
378   return t;
379 }
GetReferenceableValue(long long t)380 inline constexpr long long GetReferenceableValue(long long t) {  // NOLINT
381   return t;
382 }
GetReferenceableValue(unsigned long long t)383 inline constexpr unsigned long long GetReferenceableValue(  // NOLINT
384     unsigned long long t) {                                 // NOLINT
385   return t;
386 }
387 
388 }  // namespace log_internal
389 ABSL_NAMESPACE_END
390 }  // namespace absl
391 
392 #endif  // ABSL_LOG_INTERNAL_CHECK_OP_H_
393