diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-09-20 22:18:02 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-09-20 22:18:02 +0000 |
commit | 186af2de86aea41d7418158e68f96c1f8620e013 (patch) | |
tree | 73675134bcac9f35f0865577ed44c1aece5d30bd /lib/Analysis/ThreadSafety.cpp | |
parent | 8b533d97e0683a0c87096b95927a2e9ce02243d4 (diff) |
Thread safety analysis: properly canonicalize calls to virtual methods within
lock expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164324 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | lib/Analysis/ThreadSafety.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index 036d0b8888..fd59556665 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/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) { |