Use of WTF::move prevents clang's move diagnostics from warning about several classes...
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Dec 2015 05:24:12 +0000 (05:24 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 31 Dec 2015 05:24:12 +0000 (05:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152601

Reviewed by Brady Eidson.

Clang has recently added warnings to catch certain classes of mistakes with the use of std::move():
-Wpessimizing-move (warns if moving prevents copy elision), -Wredundant-move (warns if a move is redundant),
and -Wself-move (warns if moving to self). Enabling these warnings manually (by renaming WTF::move to std::move)
have caught numerous mistakes in our codebase (see http://trac.webkit.org/changeset/194428).

It would be nice to be able to take advantage of these warnings, but doing so requires that we use std::move,
not WTF::move. But since WTF::move does provide useful checks for which clang does not yet have warnings,
we should write a best-of-both-worlds move function.

This patch adds a function that satisfies clang's criteria for a move function (in namespace std, named "move",
and takes a single argument) but also retains WTF::move's compile-time checks. It also adds a convenience macro
called WTF_MOVE for use by callers.

* wtf/StdLibExtras.h:
(std::move):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194451 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/StdLibExtras.h

index a8cfe55..5d57832 100644 (file)
@@ -1,3 +1,26 @@
+2015-12-30  Andy Estes  <aestes@apple.com>
+
+        Use of WTF::move prevents clang's move diagnostics from warning about several classes of mistakes
+        https://bugs.webkit.org/show_bug.cgi?id=152601
+
+        Reviewed by Brady Eidson.
+
+        Clang has recently added warnings to catch certain classes of mistakes with the use of std::move():
+        -Wpessimizing-move (warns if moving prevents copy elision), -Wredundant-move (warns if a move is redundant),
+        and -Wself-move (warns if moving to self). Enabling these warnings manually (by renaming WTF::move to std::move)
+        have caught numerous mistakes in our codebase (see http://trac.webkit.org/changeset/194428).
+
+        It would be nice to be able to take advantage of these warnings, but doing so requires that we use std::move,
+        not WTF::move. But since WTF::move does provide useful checks for which clang does not yet have warnings,
+        we should write a best-of-both-worlds move function.
+
+        This patch adds a function that satisfies clang's criteria for a move function (in namespace std, named "move",
+        and takes a single argument) but also retains WTF::move's compile-time checks. It also adds a convenience macro
+        called WTF_MOVE for use by callers.
+
+        * wtf/StdLibExtras.h:
+        (std::move):
+
 2015-12-25  Andy Estes  <aestes@apple.com>
 
         Stop moving local objects in return statements
index 92ba430..e06513c 100644 (file)
@@ -111,6 +111,8 @@ inline bool isPointerTypeAlignmentOkay(Type*)
 
 namespace WTF {
 
+enum CheckMoveParameterTag { CheckMoveParameter };
+
 // FIXME: Using this function prevents Clang's move diagnostics (-Wpessimizing-move, -Wredundant-move, -Wself-move) from
 // finding mistakes, since these diagnostics only evaluate calls to std::move().
 template<typename T>
@@ -381,8 +383,22 @@ namespace chrono_literals {
 }
 }
 #endif
+
+template<WTF::CheckMoveParameterTag, typename T>
+ALWAYS_INLINE CONSTEXPR typename remove_reference<T>::type&& move(T&& value)
+{
+    static_assert(is_lvalue_reference<T>::value, "T is not an lvalue reference; move() is unnecessary.");
+
+    using NonRefQualifiedType = typename remove_reference<T>::type;
+    static_assert(!is_const<NonRefQualifiedType>::value, "T is const qualified.");
+
+    return move(forward<T>(value));
 }
 
+} // namespace std
+
+#define WTF_MOVE(value) std::move<WTF::CheckMoveParameter>(value)
+
 using WTF::KB;
 using WTF::MB;
 using WTF::isCompilationThread;