Author: dcoughlin Date: Sun Nov 15 11:48:22 2015 New Revision: 253176 URL: http://llvm.org/viewvc/llvm-project?rev=253176&view=rev Log: [analyzer] Handle calling ObjC super method from inside C++ lambda.
When calling a ObjC method on super from inside a C++ lambda, look at the captures to find "self". This mirrors how the analyzer handles calling super in an ObjC block and fixes an assertion failure. rdar://problem/23550077 Added: cfe/trunk/test/Analysis/lambdas.mm Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp?rev=253176&r1=253175&r2=253176&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp (original) +++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Sun Nov 15 11:48:22 2015 @@ -148,6 +148,23 @@ const ImplicitParamDecl *AnalysisDeclCon } } + auto *CXXMethod = dyn_cast<CXXMethodDecl>(D); + if (!CXXMethod) + return nullptr; + + const CXXRecordDecl *parent = CXXMethod->getParent(); + if (!parent->isLambda()) + return nullptr; + + for (const LambdaCapture &LC : parent->captures()) { + if (!LC.capturesVariable()) + continue; + + VarDecl *VD = LC.getCapturedVar(); + if (VD->getName() == "self") + return dyn_cast<ImplicitParamDecl>(VD); + } + return nullptr; } Added: cfe/trunk/test/Analysis/lambdas.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/lambdas.mm?rev=253176&view=auto ============================================================================== --- cfe/trunk/test/Analysis/lambdas.mm (added) +++ cfe/trunk/test/Analysis/lambdas.mm Sun Nov 15 11:48:22 2015 @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-objc-root-class -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s + +int clang_analyzer_eval(int); + +@interface Super +- (void)superMethod; +@end + +@interface Sub : Super { + int _ivar1; + int _ivar2; +} +@end + + +@implementation Sub +- (void)callMethodOnSuperInCXXLambda; { + // Explicit capture. + [self]() { + [super superMethod]; + }(); + + // Implicit capture. + [=]() { + [super superMethod]; + }(); +} + +- (void)swapIvars { + int tmp = _ivar1; + _ivar1 = _ivar2; + _ivar2 = tmp; +} + +- (void)callMethodOnSelfInCXXLambda; { + _ivar1 = 7; + _ivar2 = 8; + [self]() { + [self swapIvars]; + }(); + + clang_analyzer_eval(_ivar1 == 8); // expected-warning{{TRUE}} + clang_analyzer_eval(_ivar2 == 7); // expected-warning{{TRUE}} +} + +@end _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits