LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/base - checks.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 17 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 256 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright 2006 The WebRTC Project Authors. All rights reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #ifndef WEBRTC_BASE_CHECKS_H_
      12             : #define WEBRTC_BASE_CHECKS_H_
      13             : 
      14             : #include "webrtc/typedefs.h"
      15             : 
      16             : // If you for some reson need to know if DCHECKs are on, test the value of
      17             : // RTC_DCHECK_IS_ON. (Test its value, not if it's defined; it'll always be
      18             : // defined, to either a true or a false value.)
      19             : #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
      20             : #define RTC_DCHECK_IS_ON 1
      21             : #else
      22             : #define RTC_DCHECK_IS_ON 0
      23             : #endif
      24             : 
      25             : #ifdef __cplusplus
      26             : extern "C" {
      27             : #endif
      28             : NO_RETURN void rtc_FatalMessage(const char* file, int line, const char* msg);
      29             : #ifdef __cplusplus
      30             : }  // extern "C"
      31             : #endif
      32             : 
      33             : #ifdef __cplusplus
      34             : // C++ version.
      35             : 
      36             : #include <sstream>
      37             : #include <string>
      38             : 
      39             : #include "webrtc/base/safe_compare.h"
      40             : 
      41             : // The macros here print a message to stderr and abort under various
      42             : // conditions. All will accept additional stream messages. For example:
      43             : // RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar.";
      44             : //
      45             : // - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't,
      46             : //   it's better to terminate the process than to continue. During development,
      47             : //   the reason that it's better to terminate might simply be that the error
      48             : //   handling code isn't in place yet; in production, the reason might be that
      49             : //   the author of the code truly believes that x will always be true, but that
      50             : //   she recognizes that if she is wrong, abrupt and unpleasant process
      51             : //   termination is still better than carrying on with the assumption violated.
      52             : //
      53             : //   RTC_CHECK always evaluates its argument, so it's OK for x to have side
      54             : //   effects.
      55             : //
      56             : // - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always
      57             : //   true---except that x will only be evaluated in debug builds; in production
      58             : //   builds, x is simply assumed to be true. This is useful if evaluating x is
      59             : //   expensive and the expected cost of failing to detect the violated
      60             : //   assumption is acceptable. You should not handle cases where a production
      61             : //   build fails to spot a violated condition, even those that would result in
      62             : //   crashes. If the code needs to cope with the error, make it cope, but don't
      63             : //   call RTC_DCHECK; if the condition really can't occur, but you'd sleep
      64             : //   better at night knowing that the process will suicide instead of carrying
      65             : //   on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK.
      66             : //
      67             : //   RTC_DCHECK only evaluates its argument in debug builds, so if x has visible
      68             : //   side effects, you need to write e.g.
      69             : //     bool w = x; RTC_DCHECK(w);
      70             : //
      71             : // - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are
      72             : //   specialized variants of RTC_CHECK and RTC_DCHECK that print prettier
      73             : //   messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and
      74             : //   RTC_DCHECK.
      75             : //
      76             : // - FATAL() aborts unconditionally.
      77             : //
      78             : // TODO(ajm): Ideally, checks.h would be combined with logging.h, but
      79             : // consolidation with system_wrappers/logging.h should happen first.
      80             : 
      81             : namespace rtc {
      82             : 
      83             : // Helper macro which avoids evaluating the arguments to a stream if
      84             : // the condition doesn't hold.
      85             : #define RTC_LAZY_STREAM(stream, condition)                                    \
      86             :   !(condition) ? static_cast<void>(0) : rtc::FatalMessageVoidify() & (stream)
      87             : 
      88             : // The actual stream used isn't important. We reference |ignored| in the code
      89             : // but don't evaluate it; this is to avoid "unused variable" warnings (we do so
      90             : // in a particularly convoluted way with an extra ?: because that appears to be
      91             : // the simplest construct that keeps Visual Studio from complaining about
      92             : // condition being unused).
      93             : #define RTC_EAT_STREAM_PARAMETERS(ignored) \
      94             :   (true ? true : ((void)(ignored), true))  \
      95             :       ? static_cast<void>(0)               \
      96             :       : rtc::FatalMessageVoidify() & rtc::FatalMessage("", 0).stream()
      97             : 
      98             : // Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if
      99             : // values of the same types as |a| and |b| can't be compared with the given
     100             : // operation, and that would evaluate |a| and |b| if evaluated.
     101             : #define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \
     102             :   RTC_EAT_STREAM_PARAMETERS(((void)rtc::safe_cmp::op(a, b)))
     103             : 
     104             : // RTC_CHECK dies with a fatal error if condition is not true. It is *not*
     105             : // controlled by NDEBUG or anything else, so the check will be executed
     106             : // regardless of compilation mode.
     107             : //
     108             : // We make sure RTC_CHECK et al. always evaluates their arguments, as
     109             : // doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom.
     110             : #define RTC_CHECK(condition)                                      \
     111             :   RTC_LAZY_STREAM(rtc::FatalMessage(__FILE__, __LINE__).stream(), \
     112             :                   !(condition))                                   \
     113             :       << "Check failed: " #condition << std::endl << "# "
     114             : 
     115             : // Helper macro for binary operators.
     116             : // Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
     117             : //
     118             : // TODO(akalin): Rewrite this so that constructs like if (...)
     119             : // RTC_CHECK_EQ(...) else { ... } work properly.
     120             : #define RTC_CHECK_OP(name, op, val1, val2)                                 \
     121             :   if (std::string* _result =                                               \
     122             :           rtc::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \
     123             :     rtc::FatalMessage(__FILE__, __LINE__, _result).stream()
     124             : 
     125             : // Build the error message string.  This is separate from the "Impl"
     126             : // function template because it is not performance critical and so can
     127             : // be out of line, while the "Impl" code should be inline.  Caller
     128             : // takes ownership of the returned string.
     129             : template<class t1, class t2>
     130           0 : std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
     131           0 :   std::ostringstream ss;
     132           0 :   ss << names << " (" << v1 << " vs. " << v2 << ")";
     133           0 :   std::string* msg = new std::string(ss.str());
     134           0 :   return msg;
     135             : }
     136             : 
     137             : // MSVC doesn't like complex extern templates and DLLs.
     138             : #if !defined(COMPILER_MSVC)
     139             : // Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
     140             : // in logging.cc.
     141             : extern template std::string* MakeCheckOpString<int, int>(
     142             :     const int&, const int&, const char* names);
     143             : extern template
     144             : std::string* MakeCheckOpString<unsigned long, unsigned long>(
     145             :     const unsigned long&, const unsigned long&, const char* names);
     146             : extern template
     147             : std::string* MakeCheckOpString<unsigned long, unsigned int>(
     148             :     const unsigned long&, const unsigned int&, const char* names);
     149             : extern template
     150             : std::string* MakeCheckOpString<unsigned int, unsigned long>(
     151             :     const unsigned int&, const unsigned long&, const char* names);
     152             : extern template
     153             : std::string* MakeCheckOpString<std::string, std::string>(
     154             :     const std::string&, const std::string&, const char* name);
     155             : #endif
     156             : 
     157             : // Helper functions for RTC_CHECK_OP macro.
     158             : // The (int, int) specialization works around the issue that the compiler
     159             : // will not instantiate the template version of the function on values of
     160             : // unnamed enum type - see comment below.
     161             : #define DEFINE_RTC_CHECK_OP_IMPL(name)                                       \
     162             :   template <class t1, class t2>                                              \
     163             :   inline std::string* Check##name##Impl(const t1& v1, const t2& v2,          \
     164             :                                         const char* names) {                 \
     165             :     if (rtc::safe_cmp::name(v1, v2))                                         \
     166             :       return NULL;                                                           \
     167             :     else                                                                     \
     168             :       return rtc::MakeCheckOpString(v1, v2, names);                          \
     169             :   }                                                                          \
     170             :   inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
     171             :     if (rtc::safe_cmp::name(v1, v2))                                         \
     172             :       return NULL;                                                           \
     173             :     else                                                                     \
     174             :       return rtc::MakeCheckOpString(v1, v2, names);                          \
     175             :   }
     176           0 : DEFINE_RTC_CHECK_OP_IMPL(Eq)
     177           0 : DEFINE_RTC_CHECK_OP_IMPL(Ne)
     178           0 : DEFINE_RTC_CHECK_OP_IMPL(Le)
     179           0 : DEFINE_RTC_CHECK_OP_IMPL(Lt)
     180           0 : DEFINE_RTC_CHECK_OP_IMPL(Ge)
     181           0 : DEFINE_RTC_CHECK_OP_IMPL(Gt)
     182             : #undef DEFINE_RTC_CHECK_OP_IMPL
     183             : 
     184             : #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2)
     185             : #define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2)
     186             : #define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(Le, <=, val1, val2)
     187             : #define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(Lt, <, val1, val2)
     188             : #define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(Ge, >=, val1, val2)
     189             : #define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(Gt, >, val1, val2)
     190             : 
     191             : // The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates
     192             : // code in debug builds. It does reference the condition parameter in all cases,
     193             : // though, so callers won't risk getting warnings about unused variables.
     194             : #if RTC_DCHECK_IS_ON
     195             : #define RTC_DCHECK(condition) RTC_CHECK(condition)
     196             : #define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2)
     197             : #define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2)
     198             : #define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2)
     199             : #define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2)
     200             : #define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2)
     201             : #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2)
     202             : #else
     203             : #define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition)
     204             : #define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Eq, v1, v2)
     205             : #define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ne, v1, v2)
     206             : #define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Le, v1, v2)
     207             : #define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Lt, v1, v2)
     208             : #define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ge, v1, v2)
     209             : #define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Gt, v1, v2)
     210             : #endif
     211             : 
     212             : // This is identical to LogMessageVoidify but in name.
     213             : class FatalMessageVoidify {
     214             :  public:
     215           0 :   FatalMessageVoidify() { }
     216             :   // This has to be an operator with a precedence lower than << but
     217             :   // higher than ?:
     218           0 :   void operator&(std::ostream&) { }
     219             : };
     220             : 
     221             : #define RTC_UNREACHABLE_CODE_HIT false
     222             : #define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT)
     223             : 
     224             : #define FATAL() rtc::FatalMessage(__FILE__, __LINE__).stream()
     225             : // TODO(ajm): Consider adding RTC_NOTIMPLEMENTED macro when
     226             : // base/logging.h and system_wrappers/logging.h are consolidated such that we
     227             : // can match the Chromium behavior.
     228             : 
     229             : // Like a stripped-down LogMessage from logging.h, except that it aborts.
     230             : class FatalMessage {
     231             :  public:
     232             :   FatalMessage(const char* file, int line);
     233             :   // Used for RTC_CHECK_EQ(), etc. Takes ownership of the given string.
     234             :   FatalMessage(const char* file, int line, std::string* result);
     235             :   NO_RETURN ~FatalMessage();
     236             : 
     237           0 :   std::ostream& stream() { return stream_; }
     238             : 
     239             :  private:
     240             :   void Init(const char* file, int line);
     241             : 
     242             :   std::ostringstream stream_;
     243             : };
     244             : 
     245             : // Performs the integer division a/b and returns the result. CHECKs that the
     246             : // remainder is zero.
     247             : template <typename T>
     248           0 : inline T CheckedDivExact(T a, T b) {
     249           0 :   RTC_CHECK_EQ(a % b, 0) << a << " is not evenly divisible by " << b;
     250           0 :   return a / b;
     251             : }
     252             : 
     253             : }  // namespace rtc
     254             : 
     255             : #else  // __cplusplus not defined
     256             : // C version. Lacks many features compared to the C++ version, but usage
     257             : // guidelines are the same.
     258             : 
     259             : #define RTC_CHECK(condition)                                             \
     260             :   do {                                                                   \
     261             :     if (!(condition)) {                                                  \
     262             :       rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \
     263             :     }                                                                    \
     264             :   } while (0)
     265             : 
     266             : #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b))
     267             : #define RTC_CHECK_NE(a, b) RTC_CHECK((a) != (b))
     268             : #define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b))
     269             : #define RTC_CHECK_LT(a, b) RTC_CHECK((a) < (b))
     270             : #define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b))
     271             : #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b))
     272             : 
     273             : #define RTC_DCHECK(condition)                                             \
     274             :   do {                                                                    \
     275             :     if (RTC_DCHECK_IS_ON && !(condition)) {                               \
     276             :       rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \
     277             :     }                                                                     \
     278             :   } while (0)
     279             : 
     280             : #define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b))
     281             : #define RTC_DCHECK_NE(a, b) RTC_DCHECK((a) != (b))
     282             : #define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b))
     283             : #define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b))
     284             : #define RTC_DCHECK_GE(a, b) RTC_DCHECK((a) >= (b))
     285             : #define RTC_DCHECK_GT(a, b) RTC_DCHECK((a) > (b))
     286             : 
     287             : #endif  // __cplusplus
     288             : 
     289             : #endif  // WEBRTC_BASE_CHECKS_H_

Generated by: LCOV version 1.13