r276900 - [Sema] Teach getCurrentThisType to reconize lambda in in-class initializer
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 11 15:15:40 PDT 2016
On Thu, Aug 11, 2016 at 1:38 PM, Faisal Vali <faisalv at gmail.com> wrote:
> 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.
Ah, thanks, I agree. Looks like it's just the comment that's slightly
misleading.
> >
> > 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
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160811/f3fbcc17/attachment-0001.html>
More information about the cfe-commits
mailing list