summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2012-09-20 22:18:02 +0000
committerDeLesley Hutchins <delesley@google.com>2012-09-20 22:18:02 +0000
commitb78aeed26e65c577b2b629e9163b21792016d43a (patch)
tree93265b60d34a2d59bcb36de54e362eee3f6a5577 /clang/lib/Analysis/ThreadSafety.cpp
parenta05b3b5435a130d36798835980c9374636152ecf (diff)
downloadbcm5719-llvm-b78aeed26e65c577b2b629e9163b21792016d43a.tar.gz
bcm5719-llvm-b78aeed26e65c577b2b629e9163b21792016d43a.zip
Thread safety analysis: properly canonicalize calls to virtual methods within
lock expressions. llvm-svn: 164324
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 036d0b8888a..fd595566651 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -226,8 +226,21 @@ private:
return NodeVec.size()-1;
}
- unsigned makeMCall(unsigned NumArgs, const NamedDecl *D) {
- NodeVec.push_back(SExprNode(EOP_MCall, NumArgs, D));
+ // Grab the very first declaration of virtual method D
+ const CXXMethodDecl* getFirstVirtualDecl(const CXXMethodDecl *D) {
+ while (true) {
+ D = D->getCanonicalDecl();
+ CXXMethodDecl::method_iterator I = D->begin_overridden_methods(),
+ E = D->end_overridden_methods();
+ if (I == E)
+ return D; // Method does not override anything
+ D = *I; // FIXME: this does not work with multiple inheritance.
+ }
+ return 0;
+ }
+
+ unsigned makeMCall(unsigned NumArgs, const CXXMethodDecl *D) {
+ NodeVec.push_back(SExprNode(EOP_MCall, NumArgs, getFirstVirtualDecl(D)));
return NodeVec.size()-1;
}
@@ -328,8 +341,7 @@ private:
return buildSExpr(CMCE->getImplicitObjectArgument(), CallCtx, NDeref);
}
unsigned NumCallArgs = CMCE->getNumArgs();
- unsigned Root =
- makeMCall(NumCallArgs, CMCE->getMethodDecl()->getCanonicalDecl());
+ unsigned Root = makeMCall(NumCallArgs, CMCE->getMethodDecl());
unsigned Sz = buildSExpr(CMCE->getImplicitObjectArgument(), CallCtx);
Expr** CallArgs = CMCE->getArgs();
for (unsigned i = 0; i < NumCallArgs; ++i) {
OpenPOWER on IntegriCloud