r276900 - [Sema] Teach getCurrentThisType to reconize lambda in in-class initializer

Faisal Vali via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 11 13:38:14 PDT 2016


On Thu, Aug 11, 2016 at 1:07 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> Yes, this should be merged. It's not quite right, but it's certainly better
> than what we had before.

I would agree  that the comment is broken - but, unless i'm missing
something subtle, the subsequent logic and call to
adjustCVQualifiersForCXXThisWithinLambda should handle the scenario
you describe.

>
> On Mon, Aug 8, 2016 at 1:34 PM, Hans Wennborg <hans at chromium.org> wrote:
>>
>> Richard: ping?
>>
>> On Wed, Jul 27, 2016 at 4:46 PM, Hans Wennborg <hans at 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 at 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 at lists.llvm.org
>> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>


More information about the cfe-commits mailing list