Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1376)

Unified Diff: base/logging.h

Issue 2669213005: Add new macro "ANALYZER_ASSUME_TRUE" and integrate with all assertion types. (Closed)
Patch Set: Fix wonky formatting Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/logging.h
diff --git a/base/logging.h b/base/logging.h
index 5174e6d375540cd0f0bf355034c17812a66bf37b..3f4f5423b2410dedd2124699dd9894fe1de1f01f 100644
--- a/base/logging.h
+++ b/base/logging.h
@@ -289,6 +289,29 @@ typedef bool (*LogMessageHandlerFunction)(int severity,
BASE_EXPORT void SetLogMessageHandler(LogMessageHandlerFunction handler);
BASE_EXPORT LogMessageHandlerFunction GetLogMessageHandler();
+// ANALYSIS_MARK_ASSERTION(...) adds compiler-specific annotations to an
+// asserted condition which stop static analysis if the asserted condition is
+// untrue.
+#if defined(__clang_analyzer__)
+
+inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
+ return false;
+}
+
+#define ANALYSIS_MARK_ASSERTION(condition) \
+ (!!(condition) || logging::AnalyzerNoReturn())
+
+#elif defined(_PREFAST_) && defined(OS_WIN)
+
+#define ANALYSIS_MARK_ASSERTION(condition) __analysis_assume(!!(condition))
+
+#else // !_PREFAST_ & !__clang_analyzer__
+
+// No analyzer attached - just pass it through.
+#define ANALYSIS_MARK_ASSERTION(condition) !!(condition)
brucedawson 2017/02/02 21:37:57 Why the double ! here? They are needed in the /ana
Kevin M 2017/02/02 21:46:43 Wasn't sure if casting to a bool in this way yield
+
+#endif // !_PREFAST_ & !__clang_analyzer__
+
typedef int LogSeverity;
const LogSeverity LOG_VERBOSE = -1; // This is level 1 verbosity
// Note: the log severities are used to index into the array of names,
@@ -408,8 +431,9 @@ const LogSeverity LOG_0 = LOG_ERROR;
// TODO(akalin): Add more VLOG variants, e.g. VPLOG.
-#define LOG_ASSERT(condition) \
- LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
+#define LOG_ASSERT(condition) \
+ LOG_IF(FATAL, !ANALYSIS_MARK_ASSERTION(condition)) \
+ << "Assert failed: " #condition ". "
#if defined(OS_WIN)
#define PLOG_STREAM(severity) \
@@ -482,8 +506,9 @@ class CheckOpResult {
// This is not calling BreakDebugger since this is called frequently, and
// calling an out-of-line function instead of a noreturn inline macro prevents
// compiler optimizations.
-#define CHECK(condition) \
- UNLIKELY(!(condition)) ? IMMEDIATE_CRASH() : EAT_STREAM_PARAMETERS
+#define CHECK(condition) \
+ UNLIKELY(!ANALYSIS_MARK_ASSERTION(condition)) ? IMMEDIATE_CRASH() \
+ : EAT_STREAM_PARAMETERS
#define PCHECK(condition) CHECK(condition)
@@ -492,33 +517,29 @@ class CheckOpResult {
#else // !(OFFICIAL_BUILD && NDEBUG)
#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
+// 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 CHECK(condition) \
+ ANALYSIS_MARK_ASSERTION(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 ". "
+#define PCHECK(condition) \
+ ANALYSIS_MARK_ASSERTION(condition) \
+ , LAZY_STREAM(PLOG_STREAM(FATAL), false) << "Check failed: " #condition ". "
#else // _PREFAST_
// Do as much work as possible out of line to reduce inline code size.
#define CHECK(condition) \
LAZY_STREAM(::logging::LogMessage(__FILE__, __LINE__, #condition).stream(), \
- !(condition))
+ ANALYSIS_MARK_ASSERTION(condition))
brucedawson 2017/02/02 21:37:57 I think you've gone from !(condition) to !!(condit
Kevin M 2017/02/02 21:46:44 Done.
-#define PCHECK(condition) \
- LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
- << "Check failed: " #condition ". "
+#define PCHECK(condition) \
+ LAZY_STREAM(PLOG_STREAM(FATAL), ANALYSIS_MARK_ASSERTION(condition)) \
brucedawson 2017/02/02 21:37:57 I think you've gone from !(condition) to !!(condit
Kevin M 2017/02/02 21:46:44 Done.
+ << "Check failed: " #condition ". "
#endif // _PREFAST_
@@ -716,60 +737,27 @@ const LogSeverity LOG_DCHECK = LOG_INFO;
// Note that the definition of the DCHECK macros depends on whether or not
// DCHECK_IS_ON() is true. When DCHECK_IS_ON() is false, the macros use
// EAT_STREAM_PARAMETERS to avoid expressions that would create temporaries.
-
-#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 ". "
-
-#elif defined(__clang_analyzer__)
-
-// Keeps the static analyzer from proceeding along the current codepath,
-// otherwise false positive errors may be generated by null pointer checks.
-inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
- return false;
-}
-
-#define DCHECK(condition) \
- LAZY_STREAM( \
- LOG_STREAM(DCHECK), \
- DCHECK_IS_ON() ? (logging::AnalyzerNoReturn() || !(condition)) : false) \
- << "Check failed: " #condition ". "
-
-#define DPCHECK(condition) \
- LAZY_STREAM( \
- PLOG_STREAM(DCHECK), \
- DCHECK_IS_ON() ? (logging::AnalyzerNoReturn() || !(condition)) : false) \
- << "Check failed: " #condition ". "
-
-#else
-
#if DCHECK_IS_ON()
-#define DCHECK(condition) \
- LAZY_STREAM(LOG_STREAM(DCHECK), !(condition)) \
+#define DCHECK(condition) \
+ LAZY_STREAM(LOG_STREAM(DCHECK), \
+ DCHECK_IS_ON() ? !ANALYSIS_MARK_ASSERTION(condition) : false) \
<< "Check failed: " #condition ". "
-#define DPCHECK(condition) \
- LAZY_STREAM(PLOG_STREAM(DCHECK), !(condition)) \
+
+#define DPCHECK(condition) \
+ LAZY_STREAM(PLOG_STREAM(DCHECK), \
+ DCHECK_IS_ON() ? !ANALYSIS_MARK_ASSERTION(condition) : false) \
<< "Check failed: " #condition ". "
#else // DCHECK_IS_ON()
-#define DCHECK(condition) EAT_STREAM_PARAMETERS << !(condition)
-#define DPCHECK(condition) EAT_STREAM_PARAMETERS << !(condition)
+#define DCHECK(condition) \
+ EAT_STREAM_PARAMETERS << !ANALYSIS_MARK_ASSERTION(condition)
+#define DPCHECK(condition) \
+ EAT_STREAM_PARAMETERS << !ANALYSIS_MARK_ASSERTION(condition)
#endif // DCHECK_IS_ON()
-#endif
-
// Helper macro for binary operators.
// Don't use this macro directly in your code, use DCHECK_EQ et al below.
// The 'switch' is used to prevent the 'else' from being ambiguous when the
@@ -993,7 +981,7 @@ BASE_EXPORT void RawLog(int level, const char* message);
#define RAW_CHECK(condition) \
do { \
- if (!(condition)) \
+ if (!ANALYSIS_MARK_ASSERTION(condition)) \
::logging::RawLog(::logging::LOG_FATAL, \
"Check failed: " #condition "\n"); \
} while (0)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698