Skip to content

Commit

Permalink
PR23281: Fix implementation of DR1891 to implement the intent: that i…
Browse files Browse the repository at this point in the history
…s, a

lambda-expression does not have a move-assignment operator.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@287057 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zygoloid committed Nov 16, 2016
1 parent 97fb9e6 commit 1e68aac
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 7 deletions.
6 changes: 5 additions & 1 deletion include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,11 @@ class CXXRecordDecl : public RecordDecl {
!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
Expand Down
11 changes: 8 additions & 3 deletions test/CXX/drs/dr18xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
}
4 changes: 2 additions & 2 deletions test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand All @@ -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;
Expand Down
33 changes: 33 additions & 0 deletions test/SemaCXX/lambda-expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -11161,7 +11161,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<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>
Expand Down

0 comments on commit 1e68aac

Please sign in to comment.