#else
+#if defined(_PREFAST_) && defined(OS_WIN)
+// Use __analysis_assume to tell the VC++ static analysis engine that
+// assert conditions are true, to suppress warnings. The LAZY_STREAM
+// parameter doesn't reference 'condition' in /analyze builds because
+// this evaluation confuses /analyze. The !! before condition is because
+// __analysis_assume gets confused on some conditions:
+// http://randomascii.wordpress.com/2011/09/13/analyze-for-visual-studio-the-ugly-part-5/
+
+#define CHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(LOG_STREAM(FATAL), false) \
+ << "Check failed: " #condition ". "
+
+#define PCHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(PLOG_STREAM(FATAL), false) \
+ << "Check failed: " #condition ". "
+
+#else // _PREFAST_
+
#define CHECK(condition) \
LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
<< "Check failed: " #condition ". "
-#define PCHECK(condition) \
+#define PCHECK(condition) \
LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
<< "Check failed: " #condition ". "
+#endif // _PREFAST_
+
// Helper macro for binary operators.
// Don't use this macro directly in your code, use CHECK_EQ et al below.
//
return msg;
}
-// MSVC doesn't like complex extern templates and DLLs.
-#if !defined(COMPILER_MSVC)
// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
// in logging.cc.
extern template BASE_EXPORT std::string* MakeCheckOpString<int, int>(
extern template BASE_EXPORT
std::string* MakeCheckOpString<std::string, std::string>(
const std::string&, const std::string&, const char* name);
-#endif
// Helper functions for CHECK_OP macro.
// The (int, int) specialization works around the issue that the compiler
#define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2)
#define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2)
#define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2)
+#define CHECK_IMPLIES(val1, val2) CHECK(!(val1) || (val2))
#if defined(NDEBUG)
#define ENABLE_DLOG 0
// variable warnings if the only use of a variable is in a DCHECK.
// This behavior is different from DLOG_IF et al.
-#define DCHECK(condition) \
- LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON && !(condition)) \
+#if defined(_PREFAST_) && defined(OS_WIN)
+// See comments on the previous use of __analysis_assume.
+
+#define DCHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(LOG_STREAM(DCHECK), false) \
+ << "Check failed: " #condition ". "
+
+#define DPCHECK(condition) \
+ __analysis_assume(!!(condition)), \
+ LAZY_STREAM(PLOG_STREAM(DCHECK), false) \
<< "Check failed: " #condition ". "
-#define DPCHECK(condition) \
- LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON && !(condition)) \
+#else // _PREFAST_
+
+#define DCHECK(condition) \
+ LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON ? !(condition) : false) \
<< "Check failed: " #condition ". "
+#define DPCHECK(condition) \
+ LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON ? !(condition) : false) \
+ << "Check failed: " #condition ". "
+
+#endif // _PREFAST_
+
// Helper macro for binary operators.
// Don't use this macro directly in your code, use DCHECK_EQ et al below.
#define DCHECK_OP(name, op, val1, val2) \
#define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2)
#define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2)
#define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2)
+#define DCHECK_IMPLIES(val1, val2) DCHECK(!(val1) || (val2))
-#if defined(NDEBUG) && defined(OS_CHROMEOS)
+#if !DCHECK_IS_ON && defined(OS_CHROMEOS)
#define NOTREACHED() LOG(ERROR) << "NOTREACHED() hit in " << \
__FUNCTION__ << ". "
#else