From 0755669fecc744058f3e38da49e720066d75a5cf Mon Sep 17 00:00:00 2001 From: Benjamin Smedberg Date: Tue, 19 Nov 2013 16:27:36 -0500 Subject: [PATCH] Bug 672843 part A - Create the new macro NS_WARN_IF and deprecate NS_ENSURE_* in favor of the explicit warning/return style. Also localize each macro so that it's debug and non-debug versions are local in the file, because that makes it easier for new contributors to understand. r=froydnj sr=jst --- xpcom/glue/nsDebug.h | 127 +++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 46 deletions(-) diff --git a/xpcom/glue/nsDebug.h b/xpcom/glue/nsDebug.h index 1e656c8127f..4259c2d2ac8 100644 --- a/xpcom/glue/nsDebug.h +++ b/xpcom/glue/nsDebug.h @@ -12,7 +12,7 @@ #ifndef nsError_h__ #include "nsError.h" -#endif +#endif #include "nsXPCOM.h" #include "mozilla/Assertions.h" @@ -22,7 +22,35 @@ #include "prprf.h" #endif +/** + * Warn if the given condition is true. The condition is evaluated in both + * release and debug builds, and the result is an expression which can be + * used in subsequent expressions, such as: + * + * if (NS_WARN_IF(NS_FAILED(rv)) + * return rv; + * + * This explicit warning and return is preferred to the NS_ENSURE_* macros + * which hide the warning and the return control flow. + * + * @note This is C++-only + */ +#ifdef __cplusplus #ifdef DEBUG +inline bool NS_warn_if_impl(bool condition, const char* expr, const char* file, + int32_t line) +{ + if (MOZ_UNLIKELY(condition)) { + NS_DebugBreak(NS_DEBUG_WARNING, nullptr, expr, file, line); + } + return condition; +} +#define NS_WARN_IF(condition) \ + NS_warn_if_impl(condition, #condition, __FILE__, __LINE__) +#else +#define NS_WARN_IF(condition) (bool)(condition) +#endif +#endif /** * Abort the execution of the program if the expression evaluates to @@ -40,12 +68,16 @@ * Note also that the non-debug version of this macro does not * evaluate the message argument. */ +#ifdef DEBUG #define NS_ABORT_IF_FALSE(_expr, _msg) \ do { \ if (!(_expr)) { \ NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_expr, __FILE__, __LINE__); \ } \ } while(0) +#else +#define NS_ABORT_IF_FALSE(_expr, _msg) do { /* nothing */ } while(0) +#endif /** * Warn if a given condition is false. @@ -55,103 +87,105 @@ * Note also that the non-debug version of this macro does not * evaluate the message argument. */ +#ifdef DEBUG #define NS_WARN_IF_FALSE(_expr,_msg) \ do { \ if (!(_expr)) { \ NS_DebugBreak(NS_DEBUG_WARNING, _msg, #_expr, __FILE__, __LINE__); \ } \ } while(0) +#else +#define NS_WARN_IF_FALSE(_expr, _msg) do { /* nothing */ } while(0) +#endif -/** - * Test a precondition for truth. If the expression is not true then - * trigger a program failure. - */ -#define NS_PRECONDITION(expr, str) \ - do { \ - if (!(expr)) { \ - NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \ - } \ - } while(0) /** * Test an assertion for truth. If the expression is not true then * trigger a program failure. + * + * Note that the non-debug version of this macro does not + * evaluate the message argument. */ +#ifdef DEBUG #define NS_ASSERTION(expr, str) \ do { \ if (!(expr)) { \ NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \ } \ } while(0) +#else +#define NS_ASSERTION(expr, str) do { /* nothing */ } while(0) +#endif /** - * Test a post-condition for truth. If the expression is not true then - * trigger a program failure. + * NS_PRECONDITION/POSTCONDITION are synonyms for NS_ASSERTION. */ -#define NS_POSTCONDITION(expr, str) \ - do { \ - if (!(expr)) { \ - NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \ - } \ - } while(0) +#define NS_PRECONDITION(expr, str) NS_ASSERTION(expr, str) +#define NS_POSTCONDITION(expr, str) NS_ASSERTION(expr, str) /** * This macros triggers a program failure if executed. It indicates that * an attempt was made to execute some unimplemented functionality. */ +#ifdef DEBUG #define NS_NOTYETIMPLEMENTED(str) \ NS_DebugBreak(NS_DEBUG_ASSERTION, str, "NotYetImplemented", __FILE__, __LINE__) +#else +#define NS_NOTYETIMPLEMENTED(str) do { /* nothing */ } while(0) +#endif /** * This macros triggers a program failure if executed. It indicates that - * an attempt was made to execute some unimplemented functionality. + * an attempt was made to execute a codepath which should not be reachable. */ +#ifdef DEBUG #define NS_NOTREACHED(str) \ NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Not Reached", __FILE__, __LINE__) +#else +#define NS_NOTREACHED(str) do { /* nothing */ } while(0) +#endif /** * Log an error message. */ +#ifdef DEBUG #define NS_ERROR(str) \ NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__) +#else +#define NS_ERROR(str) do { /* nothing */ } while(0) +#endif /** * Log a warning message. */ +#ifdef DEBUG #define NS_WARNING(str) \ NS_DebugBreak(NS_DEBUG_WARNING, str, nullptr, __FILE__, __LINE__) +#else +#define NS_WARNING(str) do { /* nothing */ } while(0) +#endif /** - * Trigger an abort + * Trigger an debug-only abort. + * + * @see NS_RUNTIMEABORT for release-mode asserts. */ +#ifdef DEBUG #define NS_ABORT() \ NS_DebugBreak(NS_DEBUG_ABORT, nullptr, nullptr, __FILE__, __LINE__) +#else +#define NS_ABORT() do { /* nothing */ } while(0) +#endif /** - * Cause a break + * Trigger a debugger breakpoint, only in debug builds. */ +#ifdef DEBUG #define NS_BREAK() \ NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, __FILE__, __LINE__) - -#else /* DEBUG */ - -/** - * The non-debug version of these macros do not evaluate the - * expression or the message arguments to the macro. - */ -#define NS_ABORT_IF_FALSE(_expr, _msg) do { /* nothing */ } while(0) -#define NS_WARN_IF_FALSE(_expr, _msg) do { /* nothing */ } while(0) -#define NS_PRECONDITION(expr, str) do { /* nothing */ } while(0) -#define NS_ASSERTION(expr, str) do { /* nothing */ } while(0) -#define NS_POSTCONDITION(expr, str) do { /* nothing */ } while(0) -#define NS_NOTYETIMPLEMENTED(str) do { /* nothing */ } while(0) -#define NS_NOTREACHED(str) do { /* nothing */ } while(0) -#define NS_ERROR(str) do { /* nothing */ } while(0) -#define NS_WARNING(str) do { /* nothing */ } while(0) -#define NS_ABORT() do { /* nothing */ } while(0) +#else #define NS_BREAK() do { /* nothing */ } while(0) - -#endif /* ! DEBUG */ +#endif /****************************************************************************** ** Macros for static assertions. These are used by the sixgill tool. @@ -230,7 +264,7 @@ /****************************************************************************** ** Macros for terminating execution when an unrecoverable condition is -** reached. These need to be compiled regardless of the DEBUG flag. +** reached. These need to be compiled regardless of the DEBUG flag. ******************************************************************************/ /** @@ -242,10 +276,11 @@ NS_DebugBreak(NS_DEBUG_ABORT, msg, nullptr, __FILE__, __LINE__) -/* Macros for checking the trueness of an expression passed in within an - * interface implementation. These need to be compiled regardless of the */ -/* DEBUG flag -******************************************************************************/ +/* Macros for checking the trueness of an expression passed in within an + * interface implementation. These need to be compiled regardless of the + * DEBUG flag. New code should use NS_WARN_IF(condition) instead! + * @status deprecated + */ #define NS_ENSURE_TRUE(x, ret) \ do { \