Yes, this should be merged. It's not quite right, but it's certainly better than what we had before.
On Mon, Aug 8, 2016 at 1:34 PM, Hans Wennborg <h...@chromium.org> wrote: > Richard: ping? > > On Wed, Jul 27, 2016 at 4:46 PM, Hans Wennborg <h...@chromium.org> wrote: > > Should this be merged to 3.9? > > > > Thanks, > > Hans > > > > On Wed, Jul 27, 2016 at 11:25 AM, Erik Pilkington via cfe-commits > > <cfe-commits@lists.llvm.org> wrote: > >> Author: epilk > >> Date: Wed Jul 27 13:25:10 2016 > >> New Revision: 276900 > >> > >> URL: http://llvm.org/viewvc/llvm-project?rev=276900&view=rev > >> Log: > >> [Sema] Teach getCurrentThisType to reconize lambda in in-class > initializer > >> > >> Fixes PR27994, a crash on valid. > >> > >> Differential revision: https://reviews.llvm.org/D21145 > >> > >> Modified: > >> cfe/trunk/lib/Sema/SemaExprCXX.cpp > >> cfe/trunk/test/SemaCXX/lambda-expressions.cpp > >> > >> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ > SemaExprCXX.cpp?rev=276900&r1=276899&r2=276900&view=diff > >> ============================================================ > ================== > >> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > >> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Jul 27 13:25:10 2016 > >> @@ -961,32 +961,26 @@ static QualType adjustCVQualifiersForCXX > >> QualType Sema::getCurrentThisType() { > >> DeclContext *DC = getFunctionLevelDeclContext(); > >> QualType ThisTy = CXXThisTypeOverride; > >> + > >> if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) { > >> if (method && method->isInstance()) > >> ThisTy = method->getThisType(Context); > >> } > >> - if (ThisTy.isNull()) { > >> - if (isGenericLambdaCallOperatorSpecialization(CurContext) && > >> - CurContext->getParent()->getParent()->isRecord()) { > >> - // This is a generic lambda call operator that is being > instantiated > >> - // within a default initializer - so use the enclosing class as > 'this'. > >> - // There is no enclosing member function to retrieve the 'this' > pointer > >> - // from. > >> - > >> - // FIXME: This looks wrong. If we're in a lambda within a lambda > within a > >> - // default member initializer, we need to recurse up more > parents to find > >> - // the right context. Looks like we should be walking up to the > parent of > >> - // the closure type, checking whether that is itself a lambda, > and if so, > >> - // recursing, until we reach a class or a function that isn't a > lambda > >> - // call operator. And we should accumulate the constness of > *this on the > >> - // way. > >> - > >> - QualType ClassTy = Context.getTypeDeclType( > >> - cast<CXXRecordDecl>(CurContext->getParent()->getParent())); > >> - // There are no cv-qualifiers for 'this' within default > initializers, > >> - // per [expr.prim.general]p4. > >> - ThisTy = Context.getPointerType(ClassTy); > >> - } > >> + > >> + if (ThisTy.isNull() && isLambdaCallOperator(CurContext) && > >> + !ActiveTemplateInstantiations.empty()) { > >> + > >> + assert(isa<CXXRecordDecl>(DC) && > >> + "Trying to get 'this' type from static method?"); > >> + > >> + // This is a lambda call operator that is being instantiated as a > default > >> + // initializer. DC must point to the enclosing class type, so we > can recover > >> + // the 'this' type from it. > >> + > >> + QualType ClassTy = Context.getTypeDeclType(cast< > CXXRecordDecl>(DC)); > >> + // There are no cv-qualifiers for 'this' within default > initializers, > >> + // per [expr.prim.general]p4. > This is wrong in C++17 onwards: if *this is captured by value by a non-mutable lambda, it should become const-qualified. > >> + ThisTy = Context.getPointerType(ClassTy); > >> } > >> > >> // If we are within a lambda's call operator, the cv-qualifiers of > 'this' > >> > >> Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp > >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > SemaCXX/lambda-expressions.cpp?rev=276900&r1=276899&r2=276900&view=diff > >> ============================================================ > ================== > >> --- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original) > >> +++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Wed Jul 27 13:25:10 > 2016 > >> @@ -1,5 +1,4 @@ > >> -// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify > -fblocks %s > >> -// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify > -fblocks %s > >> +// RUN: %clang_cc1 -std=c++14 -Wno-unused-value -fsyntax-only -verify > -fblocks %s > >> > >> namespace std { class type_info; }; > >> > >> @@ -499,3 +498,30 @@ void foo() { > >> }; > >> } > >> } > >> + > >> +namespace PR27994 { > >> +struct A { template <class T> A(T); }; > >> + > >> +template <class T> > >> +struct B { > >> + int x; > >> + A a = [&] { int y = x; }; > >> + A b = [&] { [&] { [&] { int y = x; }; }; }; > >> + A d = [&](auto param) { int y = x; }; > >> + A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; > >> +}; > >> + > >> +B<int> b; > >> + > >> +template <class T> struct C { > >> + struct D { > >> + int x; > >> + A f = [&] { int y = x; }; > >> + }; > >> +}; > >> + > >> +int func() { > >> + C<int> a; > >> + decltype(a)::D b; > >> +} > >> +} > >> > >> > >> _______________________________________________ > >> 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