Awesome - should/does this mean stateless lambdas can be used in uninitialized contexts?
std::set<foo, decltype([](const foo& LHS, const foo& RHS) { return ...; })> s; Would be kind of neat/handy (so you didn't have to pass in the comparator on construction, etc) On Thu, Sep 27, 2018 at 3:48 PM Richard Smith via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: rsmith > Date: Thu Sep 27 15:47:04 2018 > New Revision: 343279 > > URL: http://llvm.org/viewvc/llvm-project?rev=343279&view=rev > Log: > [cxx2a] P0624R2: Lambdas with no capture-default are > default-constructible and assignable. > > Added: > cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp > Modified: > cfe/trunk/include/clang/AST/DeclCXX.h > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/AST/DeclCXX.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/test/SemaCXX/cxx17-compat.cpp > cfe/trunk/www/cxx_status.html > > Modified: cfe/trunk/include/clang/AST/DeclCXX.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/DeclCXX.h (original) > +++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 27 15:47:04 2018 > @@ -974,10 +974,7 @@ public: > bool needsImplicitDefaultConstructor() const { > return !data().UserDeclaredConstructor && > !(data().DeclaredSpecialMembers & SMF_DefaultConstructor) && > - // C++14 [expr.prim.lambda]p20: > - // The closure type associated with a lambda-expression has > no > - // default constructor. > - !isLambda(); > + (!isLambda() || lambdaIsDefaultConstructibleAndAssignable()); > } > > /// Determine whether this class has any user-declared constructors. > @@ -1167,10 +1164,7 @@ public: > !hasUserDeclaredCopyAssignment() && > !hasUserDeclaredMoveConstructor() && > !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(); > + (!isLambda() || lambdaIsDefaultConstructibleAndAssignable()); > } > > /// Determine whether we need to eagerly declare a move assignment > @@ -1210,6 +1204,10 @@ public: > /// a template). > bool isGenericLambda() const; > > + /// Determine whether this lambda should have an implicit default > constructor > + /// and copy and move assignment operators. > + bool lambdaIsDefaultConstructibleAndAssignable() const; > + > /// Retrieve the lambda call operator of the closure type > /// if this is a closure type. > CXXMethodDecl *getLambdaCallOperator() const; > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 27 > 15:47:04 2018 > @@ -6633,6 +6633,11 @@ let CategoryName = "Lambda Issue" in { > InGroup<DeprecatedThisCapture>, DefaultIgnore; > def note_deprecated_this_capture : Note< > "add an explicit capture of 'this' to capture '*this' by reference">; > + > + // C++2a default constructible / assignable lambdas. > + def warn_cxx17_compat_lambda_def_ctor_assign : Warning< > + "%select{default construction|assignment}0 of lambda is incompatible > with " > + "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; > } > > def err_return_in_captured_stmt : Error< > > Modified: cfe/trunk/lib/AST/DeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/DeclCXX.cpp (original) > +++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Sep 27 15:47:04 2018 > @@ -628,6 +628,24 @@ bool CXXRecordDecl::hasSubobjectAtOffset > return false; > } > > +bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const { > + assert(isLambda() && "not a lambda"); > + > + // C++2a [expr.prim.lambda.capture]p11: > + // The closure type associated with a lambda-expression has no default > + // constructor if the lambda-expression has a lambda-capture and a > + // defaulted default constructor otherwise. It has a deleted copy > + // assignment operator if the lambda-expression has a lambda-capture > and > + // defaulted copy and move assignment operators otherwise. > + // > + // C++17 [expr.prim.lambda]p21: > + // The closure type associated with a lambda-expression has no default > + // constructor and a deleted copy assignment operator. > + if (getLambdaCaptureDefault() != LCD_None) > + return false; > + return getASTContext().getLangOpts().CPlusPlus2a; > +} > + > void CXXRecordDecl::addedMember(Decl *D) { > if (!D->isImplicit() && > !isa<FieldDecl>(D) && > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 27 15:47:04 2018 > @@ -7088,7 +7088,8 @@ bool Sema::ShouldDeleteSpecialMember(CXX > // The closure type associated with a lambda-expression has a > // deleted (8.4.3) default constructor and a deleted copy > // assignment operator. > - if (RD->isLambda() && > + // C++2a adds back these operators if the lambda has no capture-default. > + if (RD->isLambda() && !RD->lambdaIsDefaultConstructibleAndAssignable() > && > (CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment)) { > if (Diagnose) > Diag(RD->getLocation(), diag::note_lambda_decl); > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Sep 27 15:47:04 2018 > @@ -266,6 +266,17 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl * > return true; > } > > + if (auto *MD = dyn_cast<CXXMethodDecl>(D)) { > + // Lambdas are only default-constructible or assignable in C++2a > onwards. > + if (MD->getParent()->isLambda() && > + ((isa<CXXConstructorDecl>(MD) && > + cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) || > + MD->isCopyAssignmentOperator() || > MD->isMoveAssignmentOperator())) { > + Diag(Loc, diag::warn_cxx17_compat_lambda_def_ctor_assign) > + << !isa<CXXConstructorDecl>(MD); > + } > + } > + > auto getReferencedObjCProp = [](const NamedDecl *D) -> > const ObjCPropertyDecl * { > if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) > > Modified: cfe/trunk/test/SemaCXX/cxx17-compat.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx17-compat.cpp?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/cxx17-compat.cpp (original) > +++ cfe/trunk/test/SemaCXX/cxx17-compat.cpp Thu Sep 27 15:47:04 2018 > @@ -27,3 +27,18 @@ struct B { > // expected-warning@-4 {{default member initializer for bit-field is > incompatible with C++ standards before C++2a}} > #endif > }; > + > +auto Lambda = []{}; > +decltype(Lambda) AnotherLambda; > +#if __cplusplus <= 201703L > + // expected-error@-2 {{no matching constructor}} expected-note@-3 > 2{{candidate}} > +#else > + // expected-warning@-4 {{default construction of lambda is > incompatible with C++ standards before C++2a}} > +#endif > + > +void copy_lambda() { Lambda = Lambda; } > +#if __cplusplus <= 201703L > + // expected-error@-2 {{deleted}} expected-note@-10 {{lambda}} > +#else > + // expected-warning@-4 {{assignment of lambda is incompatible with > C++ standards before C++2a}} > +#endif > > Added: cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp?rev=343279&view=auto > > ============================================================================== > --- cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp (added) > +++ cfe/trunk/test/SemaCXX/cxx2a-lambda-default-ctor-assign.cpp Thu Sep 27 > 15:47:04 2018 > @@ -0,0 +1,37 @@ > +// RUN: %clang_cc1 -std=c++2a -verify %s > + > +auto a = []{}; > +decltype(a) a2; > +void f(decltype(a) x, decltype(a) y) { > + x = y; > + x = static_cast<decltype(a)&&>(y); > +} > + > +template<typename T> > +struct X { > + constexpr X() { T::error; } // expected-error {{'::'}} > + X(const X&); > + constexpr X &operator=(const X&) { T::error; } // expected-error > {{'::'}} > + constexpr X &operator=(X&&) { T::error; } // expected-error {{'::'}} > +}; > +extern X<int> x; > +auto b = [x = x]{}; // expected-note 3{{in instantiation of}} > +decltype(b) b2; // expected-note {{in implicit default constructor}} > +void f(decltype(b) x, decltype(b) y) { > + x = y; // expected-note {{in implicit copy assignment}} > + x = static_cast<decltype(b)&&>(y); // expected-note {{in implicit move > assignment}} > +} > + > +struct Y { > + Y() = delete; // expected-note {{deleted}} > + Y(const Y&); > + Y &operator=(const Y&) = delete; // expected-note 2{{deleted}} > + Y &operator=(Y&&) = delete; > +}; > +extern Y y; > +auto c = [y = y]{}; // expected-note 3{{deleted because}} > +decltype(c) c2; // expected-error {{deleted}} > +void f(decltype(c) x, decltype(c) y) { > + x = y; // expected-error {{deleted}} > + x = static_cast<decltype(c)&&>(y); // expected-error {{deleted}} > +} > > Modified: cfe/trunk/www/cxx_status.html > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=343279&r1=343278&r2=343279&view=diff > > ============================================================================== > --- cfe/trunk/www/cxx_status.html (original) > +++ cfe/trunk/www/cxx_status.html Thu Sep 27 15:47:04 2018 > @@ -905,7 +905,7 @@ as the draft C++2a standard evolves. > <tr> > <td>Default constructible and assignable stateless lambdas</td> > <td><a href="http://wg21.link/p0624r2">P0624R2</a></td> > - <td class="none" align="center">No</td> > + <td class="svn" align="center">SVN</td> > </tr> > <tr> > <td>Lambdas in unevaluated contexts</td> > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits