r253176 - [analyzer] Handle calling ObjC super method from inside C++ lambda.
Devin Coughlin via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 15 09:48:22 PST 2015
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);
+
+ at interface Super
+- (void)superMethod;
+ at end
+
+ at interface Sub : Super {
+ int _ivar1;
+ int _ivar2;
+}
+ at end
+
+
+ at 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}}
+}
+
+ at end
More information about the cfe-commits
mailing list