summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprMember.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2017-09-17 15:37:51 +0000
committerFaisal Vali <faisalv@yahoo.com>2017-09-17 15:37:51 +0000
commitf60ebcda68ff0fa9fc0f2ec21e7a0c083a29e4d0 (patch)
tree2913434749bdee3bc1d93def9f3460fc20f9cc97 /clang/lib/Sema/SemaExprMember.cpp
parent8ab4a9696a7753c546caff4fd21826ea72370648 (diff)
downloadbcm5719-llvm-f60ebcda68ff0fa9fc0f2ec21e7a0c083a29e4d0.tar.gz
bcm5719-llvm-f60ebcda68ff0fa9fc0f2ec21e7a0c083a29e4d0.zip
Fix the second half of PR34266: Don't implicitly capture '*this' if the members are found in a class unrelated to the enclosing class.
https://bugs.llvm.org/show_bug.cgi?id=34266 For e.g. struct A { void f(int); static void f(char); }; struct B { auto foo() { return [&] (auto a) { A::f(a); // this should not cause a capture of '*this' }; } }; The patch does the following: 1) It moves the check to attempt an implicit capture of '*this' by reference into the more logical location of when the call is actually built within ActOnCallExpr (as opposed to when the unresolved-member-lookup node is created). - Reminder: A capture of '*this' by value has to always be an explicit capture. 2) It additionally checks whether the naming class of the UnresolvedMemberExpr ('A' in the example above) is related to the enclosing class ('B' above). P.S. If you have access to ISO-C++'s CWG reflector, see this thread for some potentially related discussion: http://lists.isocpp.org/core/2017/08/2851.php llvm-svn: 313487
Diffstat (limited to 'clang/lib/Sema/SemaExprMember.cpp')
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp48
1 files changed, 1 insertions, 47 deletions
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 1c34ace8562..fc776e31a47 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1001,53 +1001,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
BaseExpr = Converted.get();
}
- LambdaScopeInfo *const CurLSI = getCurLambda();
- // If this is an implicit member reference and the overloaded
- // name refers to both static and non-static member functions
- // (i.e. BaseExpr is null) and if we are currently processing a lambda,
- // check if we should/can capture 'this'...
- // Keep this example in mind:
- // struct X {
- // void f(int) { }
- // static void f(double) { }
- //
- // int g() {
- // auto L = [=](auto a) {
- // return [](int i) {
- // return [=](auto b) {
- // f(b);
- // //f(decltype(a){});
- // };
- // };
- // };
- // auto M = L(0.0);
- // auto N = M(3);
- // N(5.32); // OK, must not error.
- // return 0;
- // }
- // };
- //
- if (!BaseExpr && CurLSI) {
- SourceLocation Loc = R.getNameLoc();
- if (SS.getRange().isValid())
- Loc = SS.getRange().getBegin();
- DeclContext *EnclosingFunctionCtx = CurContext->getParent()->getParent();
- // If the enclosing function is not dependent, then this lambda is
- // capture ready, so if we can capture this, do so.
- if (!EnclosingFunctionCtx->isDependentContext()) {
- // If the current lambda and all enclosing lambdas can capture 'this' -
- // then go ahead and capture 'this' (since our unresolved overload set
- // contains both static and non-static member functions).
- if (!CheckCXXThisCapture(Loc, /*Explcit*/false, /*Diagnose*/false))
- CheckCXXThisCapture(Loc);
- } else if (CurContext->isDependentContext()) {
- // ... since this is an implicit member reference, that might potentially
- // involve a 'this' capture, mark 'this' for potential capture in
- // enclosing lambdas.
- if (CurLSI->ImpCaptureStyle != CurLSI->ImpCap_None)
- CurLSI->addPotentialThisCapture(Loc);
- }
- }
+
const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
DeclarationName MemberName = MemberNameInfo.getName();
SourceLocation MemberLoc = MemberNameInfo.getLoc();
OpenPOWER on IntegriCloud