summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorJędrzej Nowacki <jedrzej.nowacki@digia.com>2013-01-10 10:05:02 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-01-10 17:58:13 +0100
commit3b0ed624351441a2d7be45cf9582fd36955ae860 (patch)
tree49def7351d86d5824a7b6a44982c09d928544f37 /src/corelib
parent7ff47c7bfa5d58a509bb40e1f62777b8d52409ff (diff)
Protect Q_UNREACHABLE and Q_ASSUME by Q_ASSERT.
Both Q_UNREACHABLE and Q_ASSUME with an invalid condition can produce really weird side effects and crashes. Change-Id: I4d808c705ae98388ef5853e6539b70bd5e5ad34b Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qcompilerdetection.h37
-rw-r--r--src/corelib/global/qglobal.cpp4
2 files changed, 29 insertions, 12 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 2c471bdfc3..b88309d1e7 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -94,8 +94,8 @@
# define Q_FUNC_INFO __FUNCSIG__
# define Q_ALIGNOF(type) __alignof(type)
# define Q_DECL_ALIGN(n) __declspec(align(n))
-# define Q_ASSUME(expr) __assume(expr)
-# define Q_UNREACHABLE() __assume(0)
+# define Q_ASSUME_IMPL(expr) __assume(expr)
+# define Q_UNREACHABLE_IMPL() __assume(0)
# define Q_NORETURN __declspec(noreturn)
# define Q_DECL_DEPRECATED __declspec(deprecated)
# define Q_DECL_EXPORT __declspec(dllexport)
@@ -150,18 +150,18 @@
# if defined(__INTEL_COMPILER)
/* Intel C++ also masquerades as GCC */
# define Q_CC_INTEL
-# define Q_ASSUME(expr) __assume(expr)
-# define Q_UNREACHABLE() __assume(0)
+# define Q_ASSUME_IMPL(expr) __assume(expr)
+# define Q_UNREACHABLE_IMPL() __assume(0)
# elif defined(__clang__)
/* Clang also masquerades as GCC */
# define Q_CC_CLANG
-# define Q_ASSUME(expr) if (expr){} else __builtin_unreachable()
-# define Q_UNREACHABLE() __builtin_unreachable()
+# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
+# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# else
/* Plain GCC */
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-# define Q_ASSUME(expr) if (expr){} else __builtin_unreachable()
-# define Q_UNREACHABLE() __builtin_unreachable()
+# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
+# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
# endif
# endif
@@ -789,11 +789,11 @@
#ifndef Q_UNLIKELY
# define Q_UNLIKELY(x) (x)
#endif
-#ifndef Q_ASSUME
-# define Q_ASSUME(expr) qt_noop()
+#ifndef Q_ASSUME_IMPL
+# define Q_ASSUME_IMPL(expr) qt_noop()
#endif
-#ifndef Q_UNREACHABLE
-# define Q_UNREACHABLE() qt_noop()
+#ifndef Q_UNREACHABLE_IMPL
+# define Q_UNREACHABLE_IMPL() qt_noop()
#endif
#ifndef Q_ALLOC_SIZE
# define Q_ALLOC_SIZE(x)
@@ -851,4 +851,17 @@
#define qMove(x) (x)
#endif
+#define Q_UNREACHABLE() \
+ do {\
+ Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached");\
+ Q_UNREACHABLE_IMPL();\
+ } while (0)
+
+#define Q_ASSUME(Expr) \
+ do {\
+ const bool valueOfExpression = Expr;\
+ Q_ASSERT_X(valueOfExpression, "Q_ASSUME()", "Assumption in Q_ASSUME(\"" #Expr "\") was not correct");\
+ Q_ASSUME_IMPL(valueOfExpression);\
+ } while (0)
+
#endif // QCOMPILERDETECTION_H
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 3881b166b1..6818b1d64d 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1829,6 +1829,8 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
that the current code execution cannot be reached. That is, Q_ASSUME(false)
is equivalent to Q_UNREACHABLE().
+ In debug builds the condition is enforced by an assert to facilitate debugging.
+
\note Q_LIKELY() tells the compiler that the expression is likely, but not
the only possibility. Q_ASSUME tells the compiler that it is the only
possibility.
@@ -1863,6 +1865,8 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
By using this macro in impossible conditions, code coverage may be improved
as dead code paths may be eliminated.
+ In debug builds the condition is enforced by an assert to facilitate debugging.
+
\sa Q_ASSERT(), Q_ASSUME(), qFatal()
*/