summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-11-07 21:40:11 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-11-07 21:40:11 +0000
commitbbe51d86eca2e9a663813fdcc2c6893885c4e452 (patch)
tree3f0ba5198f0b956ebcb8039ca995653446b2e457
parentb9a2832874d01d6692117d9b78d1c8aa56dba063 (diff)
downloadbcm5719-llvm-bbe51d86eca2e9a663813fdcc2c6893885c4e452.tar.gz
bcm5719-llvm-bbe51d86eca2e9a663813fdcc2c6893885c4e452.zip
[ObjC++] Don't warn about pessimizing move for __block variables
rdar://33316951 llvm-svn: 317620
-rw-r--r--clang/lib/Sema/SemaInit.cpp4
-rw-r--r--clang/test/SemaObjCXX/block-variable-move.mm43
2 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index dc7fe1d92b0..5ece958ee64 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6422,6 +6422,10 @@ static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr,
if (!VD || !VD->hasLocalStorage())
return;
+ // __block variables are not moved implicitly.
+ if (VD->hasAttr<BlocksAttr>())
+ return;
+
QualType SourceType = VD->getType();
if (!SourceType->isRecordType())
return;
diff --git a/clang/test/SemaObjCXX/block-variable-move.mm b/clang/test/SemaObjCXX/block-variable-move.mm
new file mode 100644
index 00000000000..e26dffc5d04
--- /dev/null
+++ b/clang/test/SemaObjCXX/block-variable-move.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -Wpessimizing-move -Wredundant-move %s
+
+// definitions for std::move
+namespace std {
+inline namespace foo {
+template <class T> struct remove_reference { typedef T type; };
+template <class T> struct remove_reference<T&> { typedef T type; };
+template <class T> struct remove_reference<T&&> { typedef T type; };
+
+template <class T> typename remove_reference<T>::type &&move(T &&t);
+}
+}
+
+class MoveOnly {
+public:
+ MoveOnly() { }
+ MoveOnly(MoveOnly &&) = default; // expected-note 2 {{copy constructor is implicitly deleted}}
+ MoveOnly &operator=(MoveOnly &&) = default;
+ ~MoveOnly();
+};
+
+void copyInit() {
+ __block MoveOnly temp;
+ MoveOnly temp2 = temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}}
+ MoveOnly temp3 = std::move(temp); // ok
+}
+
+MoveOnly errorOnCopy() {
+ __block MoveOnly temp;
+ return temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}}
+}
+
+MoveOnly dontWarnOnMove() {
+ __block MoveOnly temp;
+ return std::move(temp); // ok
+}
+
+class MoveOnlySub : public MoveOnly {};
+
+MoveOnly dontWarnOnMoveSubclass() {
+ __block MoveOnlySub temp;
+ return std::move(temp); // ok
+}
OpenPOWER on IntegriCloud