Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv accepted this revision. faisalv added a reviewer: faisalv. faisalv added a comment. This revision is now accepted and ready to land. Committed as r272480 http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160606/161728.html http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv added a comment. *ping* http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
twoh added a comment. Hmm, yes it seems not so simple to move the call to another place. If I come up with a better idea I'll submit it as a separate patch, as I don't want to block this one. Thank you for your work, @faisalv! http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=,*this]")
I'm also a huge advocate of simple composable interfaces that do the 'one' task that they are expected (i.e. named) to do - and do it well. I thought about this some, but perhaps not exhaustively - and settled on being ok with getCurThisType, always returning the correct type for 'this' as typed/referred to in code (with the right 'cv' quals) - regardless of where it is called from. Nevertheless, I'm open to suggestions if you have a better alternative candidate for where the call to adjustCVQuals should go? Thanks for thinking about this. Faisal Vali On Fri, May 20, 2016 at 1:33 AM, Taewook Ohwrote: > twoh added a comment. > > @faisalv, thank you for the update. I wonder if getCurrentThisType() is the > best place to call adjustCVQualifiersForCXXThisWithinLambda(). It seems that > getCurrentThisType() does more than its name suggests. Is there any other > place that the adjustment function can be called? > > > http://reviews.llvm.org/D19783 > > > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
twoh added a comment. @faisalv, thank you for the update. I wonder if getCurrentThisType() is the best place to call adjustCVQualifiersForCXXThisWithinLambda(). It seems that getCurrentThisType() does more than its name suggests. Is there any other place that the adjustment function can be called? http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv added inline comments. Comment at: lib/Parse/ParseDeclCXX.cpp:3651 @@ -3652,1 +3650,3 @@ + case AttributeList::AT_Unused: +return !ScopeName && AttrName->getName().equals("maybe_unused"); default: This whitespace change shouldn't have been included - as an aside - we still strive unix style line endings right? http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv updated this revision to Diff 57733. faisalv marked an inline comment as done. faisalv added a comment. This patch addresses all of Richard's comments - except one (on which I'm awaiting some additional clarity on, before I make any changes). http://reviews.llvm.org/D19783 Files: include/clang/Sema/ScopeInfo.h lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/cxx1z-lambda-star-this.cpp Index: test/SemaCXX/cxx1z-lambda-star-this.cpp === --- test/SemaCXX/cxx1z-lambda-star-this.cpp +++ test/SemaCXX/cxx1z-lambda-star-this.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING +templateconstexpr bool is_same = false; +template constexpr bool is_same = true; namespace test_star_this { namespace ns1 { @@ -69,4 +71,137 @@ b.foo(); //expected-note{{in instantiation}} } // end main } // end ns4 +namespace ns5 { + +struct X { + double d = 3.14; + X(const volatile X&); + void foo() { + + } + + void foo() const { //expected-note{{const}} + +auto L = [*this] () mutable { + static_assert(is_same ); + ++d; + auto M = [this] { +static_assert(is_same ); +++d; +auto N = [] { + static_assert(is_same ); +}; + }; +}; + +auto L1 = [*this] { + static_assert(is_same ); + auto M = [this] () mutable { +static_assert(is_same ); +auto N = [] { + static_assert(is_same ); +}; + }; + auto M2 = [*this] () mutable { +static_assert(is_same ); +auto N = [] { + static_assert(is_same ); +}; + }; +}; +auto L2 = [this] () mutable { + static_assert(is_same ); + ++d; //expected-error{{cannot assign}} +}; +auto GL = [*this] (auto a) mutable { + static_assert(is_same ); + ++d; + auto M = [this] (auto b) { +static_assert(is_same ); +++d; +auto N = [] (auto c) { + static_assert(is_same ); +}; +N(3.14); + }; + M("abc"); +}; +GL(3.14); + + } + void foo() volatile const { +auto L = [this] () { + static_assert(is_same ); + auto M = [*this] () mutable { +static_assert(is_same ); +auto N = [this] { + static_assert(is_same ); + auto M = [] { +static_assert(is_same ); + }; +}; +auto N2 = [*this] { + static_assert(is_same ); +}; + }; + auto M2 = [*this] () { +static_assert(is_same ); +auto N = [this] { + static_assert(is_same ); +}; + }; +}; + } + +}; + +} //end ns5 +namespace ns6 { +struct X { + double d; + auto foo() const { +auto L = [*this] () mutable { + auto M = [=] (auto a) { +auto N = [this] { + ++d; + static_assert(is_same ); + auto O = [*this] { +static_assert(is_same ); + }; +}; +N(); +static_assert(is_same ); + }; + return M; +}; +return L; + } +}; + +int main() { + auto L = X{}.foo(); + auto M = L(); + M(3.14); +} +} // end ns6 +namespace ns7 { + +struct X { + double d; + X(); + X(const X&); + X(X&) = delete; + auto foo() const { +//OK - the object used to initialize our capture is a const object and so prefers the non-deleted ctor. +const auto & = [*this] { }; + } + +}; +int main() { + X x; + x.foo(); +} +} // end ns7 + } //end ns test_star_this + Index: lib/Sema/SemaExprCXX.cpp === --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -872,6 +872,92 @@ return false; } +static QualType adjustCVQualifiersForCXXThisWithinLambda( +ArrayRef FunctionScopes, QualType ThisTy, +DeclContext *CurSemaContext, ASTContext ) { + + QualType ClassType = ThisTy->getPointeeType(); + LambdaScopeInfo *CurLSI = nullptr; + DeclContext *CurDC = CurSemaContext; + + // Iterate through the stack of lambdas starting from the innermost lambda to + // the outermost lambda, checking if '*this' is ever captured by copy - since + // that could change
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv marked 5 inline comments as done. faisalv added a comment. OK - agree (and addressed in a forthcoming patch) all your comments - except for the one I could use some clarity on - please see below Comment at: lib/Sema/SemaExprCXX.cpp:910 @@ +909,3 @@ + assert(IsFirstIteration); + assert(CurLSI->CallOperator->getParent()->getParent() == CurDC); + CurDC = CurLSI->CallOperator; rsmith wrote: > Please add a comment explaining this, I have no idea what special case you're > checking for here. That special case should have been removed before submission - it crept in as I was making incremental changes to the initial patch, and getCurrentThisType was still being called from RebuildLambdaScopeInfo. (Alternatively, I might have left it in to give Richard a sense of purpose ;) Comment at: lib/Sema/SemaExprCXX.cpp:952 @@ +951,3 @@ +while (Closure && + IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) { + if (IsByCopyCapture) { rsmith wrote: > Should you really stop here if this is not captured? There could still be a > surrounding lambda with a mutable *this capture. Do you have the following example in mind? Or is it something different? void foo() const { auto L1 = [*this] { static_assert(is_same); auto M2 = [*this] () mutable { static_assert(is_same ); auto N = [] { static_assert(is_same ); }; }; }; } http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
There are tests from the test file in my patch that don't pass(*) if you just apply Oh's fix . That's not surprising since Oh's patch only meant to fix the crash, but not the 'cv' qualification issue of '*this' that we didn't have to deal with prior to by-value captures of '*this' and my initial implementation of feature patch incorrectly/incompletely handled. Also my patch attempts to simplify the code by removing the storage of 'ThisType' in the Capture, since it never gets queried, so no reason to store it (which was also what was triggering the assertion initially). (*) error: 'error' diagnostics seen but not expected: File F:\clang-trunk\llvm\tools\clang\test\semacxx\cxx1z-lambda-star-this.cpp Line 88: static_assert failed File F:\clang-trunk\llvm\tools\clang\test\semacxx\cxx1z-lambda-star-this.cpp Line 89: cannot assign to non-static data member within const member function 'foo' File F:\clang-trunk\llvm\tools\clang\test\semacxx\cxx1z-lambda-star-this.cpp Line 91: static_assert failed File F:\clang-trunk\llvm\tools\clang\test\semacxx\cxx1z-lambda-star-this.cpp Line 92: cannot assign to non-static data member within const member function 'foo' Faisal Vali On Wed, May 18, 2016 at 12:34 PM, Richard Smithwrote: > I'd also like to know whether there are cases that this patch addresses but > Taewook Oh's patch does not, as the other patch involves a lot less > complexity. > > On 18 May 2016 10:15 a.m., "Richard Smith via cfe-commits" > wrote: >> >> rsmith added inline comments. >> >> >> Comment at: lib/Sema/SemaExprCXX.cpp:898 >> @@ +897,3 @@ >> + // end of the TU) we need to be able to examine its enclosing lambdas >> and so >> + // we use the DeclContext to get a hold of the ClosureClass and query >> it for >> + // capture information. The reason we don't just resort to always >> using the >> >> No camel case for ClosureClass. >> >> >> Comment at: lib/Sema/SemaExprCXX.cpp:910 >> @@ +909,3 @@ >> + assert(IsFirstIteration); >> + assert(CurLSI->CallOperator->getParent()->getParent() == CurDC); >> + CurDC = CurLSI->CallOperator; >> >> Please add a comment explaining this, I have no idea what special case >> you're checking for here. >> >> >> Comment at: lib/Sema/SemaExprCXX.cpp:952 >> @@ +951,3 @@ >> +while (Closure && >> + IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) { >> + if (IsByCopyCapture) { >> >> Should you really stop here if this is not captured? There could still be >> a surrounding lambda with a mutable *this capture. >> >> >> Comment at: lib/Sema/SemaExprCXX.cpp:1062 >> @@ -964,1 +1061,3 @@ >> + Expr *This = >> + new (Context) CXXThisExpr(Loc, AdjustedThisTy, /*isImplicit*/ >> true); >>if (ByCopy) { >> >> faisalv wrote: >> > Hmm - I wonder if instead of using AdjustedThisTy, I should always use >> > 'ThisTy' since it is being used in the initializer expression, and should >> > probably inherit its cv qualifiers from an enclosing lambda? correct? >> Yes, don't use AdjustedThisTy here. You can test for this bug by giving >> the class both a (const T&) and a (T&)=delete copy ctor. >> >> >> http://reviews.llvm.org/D19783 >> >> >> >> ___ >> 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
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=,*this]")
OK - thanks - will take a closer look at this hopefuly this evening or tomorrow - and respond to Richard's other comments too. Faisal Vali On Wed, May 18, 2016 at 1:46 PM, Taewook Ohwrote: > twoh added a comment. > > My patch passes check-clang and the test cases in this patch as well. > > BTW, newly added test cases in the patch seem to be passed even without the > patch. Isn't the bug appears when template instantiation generates nested > lambdas (because template instantiation updates the 'context')? > > > http://reviews.llvm.org/D19783 > > > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
twoh added a comment. My patch passes check-clang and the test cases in this patch as well. BTW, newly added test cases in the patch seem to be passed even without the patch. Isn't the bug appears when template instantiation generates nested lambdas (because template instantiation updates the 'context')? http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
rsmith added a subscriber: rsmith. rsmith added a comment. I'd also like to know whether there are cases that this patch addresses but Taewook Oh's patch does not, as the other patch involves a lot less complexity. http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
I'd also like to know whether there are cases that this patch addresses but Taewook Oh's patch does not, as the other patch involves a lot less complexity. On 18 May 2016 10:15 a.m., "Richard Smith via cfe-commits" < cfe-commits@lists.llvm.org> wrote: > rsmith added inline comments. > > > Comment at: lib/Sema/SemaExprCXX.cpp:898 > @@ +897,3 @@ > + // end of the TU) we need to be able to examine its enclosing lambdas > and so > + // we use the DeclContext to get a hold of the ClosureClass and query > it for > + // capture information. The reason we don't just resort to always > using the > > No camel case for ClosureClass. > > > Comment at: lib/Sema/SemaExprCXX.cpp:910 > @@ +909,3 @@ > + assert(IsFirstIteration); > + assert(CurLSI->CallOperator->getParent()->getParent() == CurDC); > + CurDC = CurLSI->CallOperator; > > Please add a comment explaining this, I have no idea what special case > you're checking for here. > > > Comment at: lib/Sema/SemaExprCXX.cpp:952 > @@ +951,3 @@ > +while (Closure && > + IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) { > + if (IsByCopyCapture) { > > Should you really stop here if this is not captured? There could still be > a surrounding lambda with a mutable *this capture. > > > Comment at: lib/Sema/SemaExprCXX.cpp:1062 > @@ -964,1 +1061,3 @@ > + Expr *This = > + new (Context) CXXThisExpr(Loc, AdjustedThisTy, /*isImplicit*/ true); >if (ByCopy) { > > faisalv wrote: > > Hmm - I wonder if instead of using AdjustedThisTy, I should always use > 'ThisTy' since it is being used in the initializer expression, and should > probably inherit its cv qualifiers from an enclosing lambda? correct? > Yes, don't use AdjustedThisTy here. You can test for this bug by giving > the class both a (const T&) and a (T&)=delete copy ctor. > > > http://reviews.llvm.org/D19783 > > > > ___ > 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
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
rsmith added inline comments. Comment at: lib/Sema/SemaExprCXX.cpp:898 @@ +897,3 @@ + // end of the TU) we need to be able to examine its enclosing lambdas and so + // we use the DeclContext to get a hold of the ClosureClass and query it for + // capture information. The reason we don't just resort to always using the No camel case for ClosureClass. Comment at: lib/Sema/SemaExprCXX.cpp:910 @@ +909,3 @@ + assert(IsFirstIteration); + assert(CurLSI->CallOperator->getParent()->getParent() == CurDC); + CurDC = CurLSI->CallOperator; Please add a comment explaining this, I have no idea what special case you're checking for here. Comment at: lib/Sema/SemaExprCXX.cpp:952 @@ +951,3 @@ +while (Closure && + IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) { + if (IsByCopyCapture) { Should you really stop here if this is not captured? There could still be a surrounding lambda with a mutable *this capture. Comment at: lib/Sema/SemaExprCXX.cpp:1062 @@ -964,1 +1061,3 @@ + Expr *This = + new (Context) CXXThisExpr(Loc, AdjustedThisTy, /*isImplicit*/ true); if (ByCopy) { faisalv wrote: > Hmm - I wonder if instead of using AdjustedThisTy, I should always use > 'ThisTy' since it is being used in the initializer expression, and should > probably inherit its cv qualifiers from an enclosing lambda? correct? Yes, don't use AdjustedThisTy here. You can test for this bug by giving the class both a (const T&) and a (T&)=delete copy ctor. http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv added a comment. Is it too soon for a *ping* ;) p.s. just added some comments. Comment at: lib/Sema/SemaExprCXX.cpp:904 @@ +903,3 @@ + for (int I = FunctionScopes.size(); + I-- && dyn_cast(FunctionScopes[I]); + IsFirstIteration = false, That dyn_cast should be an 'isa' Comment at: lib/Sema/SemaExprCXX.cpp:1062 @@ -964,1 +1061,3 @@ + Expr *This = + new (Context) CXXThisExpr(Loc, AdjustedThisTy, /*isImplicit*/ true); if (ByCopy) { Hmm - I wonder if instead of using AdjustedThisTy, I should always use 'ThisTy' since it is being used in the initializer expression, and should probably inherit its cv qualifiers from an enclosing lambda? correct? http://reviews.llvm.org/D19783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D19783: Fix cv-qualification of '*this' captures (and nasty bug PR27507 introduced by commit 263921 "Implement Lambda Capture of *this by Value as [=, *this]")
faisalv created this revision. faisalv added reviewers: rsmith, hubert.reinterpretcast. faisalv added subscribers: cfe-commits, gnzlbg. The bug report by Gonzalo (https://llvm.org/bugs/show_bug.cgi?id=27507 -- which results in clang crashing when generic lambdas that capture 'this' are instantiated in contexts where the functionscopeinfo stack is not in a reliable state - yet getCurrentThisType expects it to be) - unearthed some additional bugs in regards to maintaining proper cv qualification through 'this' when performing by value captures of '*this'. This patch attempts to correct those bugs and makes the following changes: - when capturing 'this', we do not need to remember the type of 'this' within the LambdaScopeInfo's Capture - it is never really used for a this capture - so remove it. - teach getCurrentThisType to walk the stack of lambdas (even in scenarios where we run out of LambdaScopeInfo's such as when instantiating call operators) looking for by copy captures of '*this' and resetting the type of 'this' based on the constness of that capturing lambda's call operator. As an example, consider the member function 'foo' below and follow along with the static_asserts: void foo() const { auto L = [*this] () mutable { static_assert(is_same); ++d; auto M = [this] { static_assert(is_same ); ++d; auto N = [] { static_assert(is_same ); }; }; }; auto L1 = [*this] { static_assert(is_same ); auto M = [this] () mutable { static_assert(is_same ); auto N = [] { static_assert(is_same ); }; }; }; auto L2 = [this] () mutable { static_assert(is_same ); }; auto GL = [*this] (auto a) mutable { static_assert(is_same ); ++d; auto M = [this] (auto b) { static_assert(is_same ); ++d; auto N = [] (auto c) { static_assert(is_same ); }; N(3.14); }; M("abc"); }; GL(3.14); } Please see the test file for additional tests. Thanks! http://reviews.llvm.org/D19783 Files: include/clang/Sema/ScopeInfo.h lib/Sema/SemaDecl.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/cxx1z-lambda-star-this.cpp Index: test/SemaCXX/cxx1z-lambda-star-this.cpp === --- test/SemaCXX/cxx1z-lambda-star-this.cpp +++ test/SemaCXX/cxx1z-lambda-star-this.cpp @@ -3,6 +3,8 @@ // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING +template constexpr bool is_same = false; +template constexpr bool is_same = true; namespace test_star_this { namespace ns1 { @@ -69,4 +71,112 @@ b.foo(); //expected-note{{in instantiation}} } // end main } // end ns4 +namespace ns5 { + +struct X { + double d = 3.14; + X(const volatile X&); + void foo() { + + } + + void foo() const { //expected-note{{const}} + +auto L = [*this] () mutable { + static_assert(is_same ); + ++d; + auto M = [this] { +static_assert(is_same ); +++d; +auto N = [] { + static_assert(is_same ); +}; + }; +}; + +auto L1 = [*this] { + static_assert(is_same ); + auto M = [this] () mutable { +static_assert(is_same ); +auto N = [] { + static_assert(is_same ); +}; + }; +}; +auto L2 = [this] () mutable { + static_assert(is_same ); + ++d; //expected-error{{cannot assign}} +}; +auto GL = [*this] (auto a) mutable { + static_assert(is_same ); + ++d; + auto M = [this] (auto b) { +static_assert(is_same ); +++d; +auto N = [] (auto c) { + static_assert(is_same ); +}; +N(3.14); + }; + M("abc"); +}; +GL(3.14); + + } + void foo() volatile const { +auto L = [this] () { + static_assert(is_same ); + auto M = [*this] () mutable { +static_assert(is_same ); +auto N = [this] { + static_assert(is_same ); + auto M = [] { +static_assert(is_same ); + }; +}; +auto N2 = [*this] { +