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

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 27 16:46:58 PDT 2016


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