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. > + 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