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

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 8 13:34:39 PDT 2016


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