Re: r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are
Excellent, excellent - thanks! On Mon, Oct 1, 2018 at 10:22 AM Richard Smith wrote: > On Mon, 1 Oct 2018, 09:55 David Blaikie via cfe-commits, < > cfe-commits@lists.llvm.org> wrote: > >> Awesome - should/does this mean stateless lambdas can be used in >> uninitialized contexts? >> >> std::set> })> s; >> >> Would be kind of neat/handy (so you didn't have to pass in the comparator >> on construction, etc) >> > > Not quite: that also needs p0315r4, but that's coming in C++20 too. > > 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=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=343278=343279=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=343278=343279=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, 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, >>> 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=343278=343279=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: >>> + //
Re: r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are
On Mon, 1 Oct 2018, 09:55 David Blaikie via cfe-commits, < cfe-commits@lists.llvm.org> wrote: > Awesome - should/does this mean stateless lambdas can be used in > uninitialized contexts? > > std::set })> s; > > Would be kind of neat/handy (so you didn't have to pass in the comparator > on construction, etc) > Not quite: that also needs p0315r4, but that's coming in C++20 too. 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=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=343278=343279=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=343278=343279=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, 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, >> 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=343278=343279=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
Re: r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are
Awesome - should/does this mean stateless lambdas can be used in uninitialized contexts? std::set 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=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=343278=343279=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=343278=343279=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, 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, 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=343278=343279=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
r343279 - [cxx2a] P0624R2: Lambdas with no capture-default are
Author: rsmith Date: Thu Sep 27 15:47:04 2018 New Revision: 343279 URL: http://llvm.org/viewvc/llvm-project?rev=343279=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=343278=343279=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=343278=343279=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, 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, 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=343278=343279=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(D) && Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=343279=343278=343279=diff == ---