summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/snippets/code/src_corelib_global_qglobal.cpp23
-rw-r--r--src/corelib/global/qcompilerdetection.h8
-rw-r--r--src/corelib/global/qglobal.cpp57
-rw-r--r--src/corelib/global/qglobal.h6
4 files changed, 94 insertions, 0 deletions
diff --git a/doc/src/snippets/code/src_corelib_global_qglobal.cpp b/doc/src/snippets/code/src_corelib_global_qglobal.cpp
index 21bea7aef8..16f6783a52 100644
--- a/doc/src/snippets/code/src_corelib_global_qglobal.cpp
+++ b/doc/src/snippets/code/src_corelib_global_qglobal.cpp
@@ -560,3 +560,26 @@ bool readConfiguration(const QFile &file)
return true;
}
//! [qunlikely]
+
+//! [qunreachable-enum]
+ enum Shapes {
+ Rectangle,
+ Triangle,
+ Circle,
+ NumShapes
+ };
+//! [qunreachable-enum]
+
+//! [qunreachable-switch]
+ switch (shape) {
+ case Rectangle:
+ return rectangle();
+ case Triangle:
+ return triangle();
+ case Circle:
+ return circle();
+ case NumShapes:
+ Q_UNREACHABLE();
+ break;
+ }
+//! [qunreachable-switch]
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index f3f0302072..c9f59454b2 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -88,6 +88,8 @@
# define Q_NO_TEMPLATE_FRIENDS
# 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)
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
# if defined(__INTEL_COMPILER)
# define Q_CC_INTEL
@@ -141,11 +143,17 @@
# 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)
# 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()
# else
/* Plain GCC */
+# define Q_ASSUME(expr) if (expr){} else __builtin_unreachable()
+# define Q_UNREACHABLE() __builtin_unreachable()
# endif
# define Q_ALIGNOF(type) __alignof__(type)
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 09d178639d..f89b0b3421 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1799,6 +1799,63 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
*/
/*!
+ \macro void Q_ASSUME(bool expr)
+ \relates <QtGlobal>
+ \since 5.0
+
+ Causes the compiler to assume that \a expr is true. This macro is useful
+ for improving code generation, by providing the compiler with hints about
+ conditions that it would not otherwise know about. However, there is no
+ guarantee that the compiler will actually use those hints.
+
+ This macro could be considered a "lighter" version of \ref Q_ASSERT. While
+ Q_ASSERT will abort the program's execution if the condition is false,
+ Q_ASSUME will tell the compiler not to generate code for those conditions.
+ Therefore, it is important that the assumptions always hold, otherwise
+ undefined behaviour may occur.
+
+ If \a expr is a constantly false condition, Q_ASSUME will tell the compiler
+ that the current code execution cannot be reached. That is, Q_ASSUME(false)
+ is equivalent to Q_UNREACHABLE().
+
+ \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.
+
+ \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY()
+*/
+
+/*!
+ \macro void Q_UNREACHABLE()
+ \relates <QtGlobal>
+ \since 5.0
+
+ Tells the compiler that the current point cannot be reached by any
+ execution, so it may optimise any code paths leading here as dead code, as
+ well as code continuing from here.
+
+ This macro is useful to mark impossible conditions. For example, given the
+ following enum:
+
+ \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp qunreachable-enum
+
+ One can write a switch table like so:
+
+ \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp qunreachable-switch
+
+ The advantage of inserting Q_UNREACHABLE() at that point is that the
+ compiler is told not to generate code for a shape variable containing that
+ value. If the macro is missing, the compiler will still generate the
+ necessary comparisons for that value. If the case label were removed, some
+ compilers could produce a warning that some enum values were not checked.
+
+ By using this macro in impossible conditions, code coverage may be improved
+ as dead code paths may be eliminated.
+
+ \sa Q_ASSERT(), Q_ASSUME(), qFatal()
+*/
+
+/*!
\macro void Q_CHECK_PTR(void *pointer)
\relates <QtGlobal>
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 734177638c..7d91fa3ca9 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -163,6 +163,12 @@ namespace QT_NAMESPACE {}
#ifndef Q_UNLIKELY
# define Q_UNLIKELY(x) (x)
#endif
+#ifndef Q_ASSUME
+# define Q_ASSUME(expr)
+#endif
+#ifndef Q_UNREACHABLE
+# define Q_UNREACHABLE()
+#endif
#ifndef Q_ALLOC_SIZE
# define Q_ALLOC_SIZE(x)