summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclCXX.h6
-rw-r--r--test/CXX/drs/dr18xx.cpp11
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp4
-rw-r--r--test/SemaCXX/lambda-expressions.cpp33
-rw-r--r--www/cxx_dr_status.html2
5 files changed, 49 insertions, 7 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 357e075786..b40ca28cef 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -993,7 +993,11 @@ public:
!hasUserDeclaredCopyConstructor() &&
!hasUserDeclaredCopyAssignment() &&
!hasUserDeclaredMoveConstructor() &&
- !hasUserDeclaredDestructor();
+ !hasUserDeclaredDestructor() &&
+ // C++1z [expr.prim.lambda]p21: "the closure type has a deleted copy
+ // assignment operator". The intent is that this counts as a user
+ // declared copy assignment, but we do not model it that way.
+ !isLambda();
}
/// \brief Determine whether we need to eagerly declare a move assignment
diff --git a/test/CXX/drs/dr18xx.cpp b/test/CXX/drs/dr18xx.cpp
index bc72b67d1e..436bccc8e4 100644
--- a/test/CXX/drs/dr18xx.cpp
+++ b/test/CXX/drs/dr18xx.cpp
@@ -7,11 +7,11 @@
// expected-no-diagnostics
#endif
-void dr1891() { // dr1891: 3.6
+void dr1891() { // dr1891: 4.0
#if __cplusplus >= 201103L
int n;
- auto a = []{}; // expected-note 2{{candidate}}
- auto b = [=]{ return n; }; // expected-note 2{{candidate}}
+ auto a = []{}; // expected-note 2{{candidate}} expected-note 2{{here}}
+ auto b = [=]{ return n; }; // expected-note 2{{candidate}} expected-note 2{{here}}
typedef decltype(a) A;
typedef decltype(b) B;
@@ -20,5 +20,10 @@ void dr1891() { // dr1891: 3.6
A x; // expected-error {{no matching constructor}}
B y; // expected-error {{no matching constructor}}
+
+ a = a; // expected-error {{copy assignment operator is implicitly deleted}}
+ a = static_cast<A&&>(a); // expected-error {{copy assignment operator is implicitly deleted}}
+ b = b; // expected-error {{copy assignment operator is implicitly deleted}}
+ b = static_cast<B&&>(b); // expected-error {{copy assignment operator is implicitly deleted}}
#endif
}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
index 40360e4069..1dbcbf4980 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -7,7 +7,7 @@ struct MoveOnly {
template<typename T> T &&move(T&);
void test_special_member_functions(MoveOnly mo, int i) {
- auto lambda1 = [i]() { }; // expected-note {{lambda expression begins here}} expected-note 2{{candidate}}
+ auto lambda1 = [i]() { }; // expected-note 2{{lambda expression begins here}} expected-note 2{{candidate}}
// Default constructor
decltype(lambda1) lambda2; // expected-error{{no matching constructor}}
@@ -16,7 +16,7 @@ void test_special_member_functions(MoveOnly mo, int i) {
lambda1 = lambda1; // expected-error{{copy assignment operator is implicitly deleted}}
// Move assignment operator
- lambda1 = move(lambda1);
+ lambda1 = move(lambda1); // expected-error{{copy assignment operator is implicitly deleted}}
// Copy constructor
decltype(lambda1) lambda3 = lambda1;
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index 5fffe41117..4d06fdf089 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -95,6 +95,39 @@ namespace ImplicitCapture {
}
}
+namespace SpecialMembers {
+ void f() {
+ auto a = []{}; // expected-note 2{{here}} expected-note 2{{candidate}}
+ decltype(a) b; // expected-error {{no matching constructor}}
+ decltype(a) c = a;
+ decltype(a) d = static_cast<decltype(a)&&>(a);
+ a = a; // expected-error {{copy assignment operator is implicitly deleted}}
+ a = static_cast<decltype(a)&&>(a); // expected-error {{copy assignment operator is implicitly deleted}}
+ }
+ struct P {
+ P(const P&) = delete; // expected-note {{deleted here}}
+ };
+ struct Q {
+ ~Q() = delete; // expected-note {{deleted here}}
+ };
+ struct R {
+ R(const R&) = default;
+ R(R&&) = delete;
+ R &operator=(const R&) = delete;
+ R &operator=(R&&) = delete;
+ };
+ void g(P &p, Q &q, R &r) {
+ auto pp = [p]{}; // expected-error {{deleted constructor}}
+ auto qq = [q]{}; // expected-error {{deleted function}} expected-note {{because}}
+
+ auto a = [r]{}; // expected-note 2{{here}}
+ decltype(a) b = a;
+ decltype(a) c = static_cast<decltype(a)&&>(a); // ok, copies R
+ a = a; // expected-error {{copy assignment operator is implicitly deleted}}
+ a = static_cast<decltype(a)&&>(a); // expected-error {{copy assignment operator is implicitly deleted}}
+ }
+}
+
namespace PR12031 {
struct X {
template<typename T>
diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index ad73e7e4fb..293535238b 100644
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -11161,7 +11161,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1891">1891</a></td>
<td>DRWP</td>
<td>Move constructor/assignment for closure class</td>
- <td class="full" align="center">Clang 3.6</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="1892">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1892">1892</a></td>