diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-12-05 01:20:45 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-12-05 01:20:45 +0000 |
commit | 91e2061763f5e59f57e59c6f141b74b5ff0408ad (patch) | |
tree | adab0c157e492edfe63314b38eff46ba179218c0 /lib/Analysis/ThreadSafety.cpp | |
parent | 39a62fcd3003785d9cc913ab2820be2f6f27bb40 (diff) |
Thread-safety analysis: check locks on method calls, operator=, and
copy constructors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169350 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | lib/Analysis/ThreadSafety.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index bc3f85c7b5..fdfd599ba5 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -2056,6 +2056,43 @@ void BuildLockset::VisitCastExpr(CastExpr *CE) { void BuildLockset::VisitCallExpr(CallExpr *Exp) { + if (Analyzer->Handler.issueBetaWarnings()) { + if (CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(Exp)) { + MemberExpr *ME = dyn_cast<MemberExpr>(CE->getCallee()); + // ME can be null when calling a method pointer + CXXMethodDecl *MD = CE->getMethodDecl(); + + if (ME && MD) { + if (ME->isArrow()) { + if (MD->isConst()) { + checkPtAccess(CE->getImplicitObjectArgument(), AK_Read); + } else { // FIXME -- should be AK_Written + checkPtAccess(CE->getImplicitObjectArgument(), AK_Read); + } + } else { + if (MD->isConst()) + checkAccess(CE->getImplicitObjectArgument(), AK_Read); + else // FIXME -- should be AK_Written + checkAccess(CE->getImplicitObjectArgument(), AK_Read); + } + } + } else if (CXXOperatorCallExpr *OE = dyn_cast<CXXOperatorCallExpr>(Exp)) { + switch (OE->getOperator()) { + case OO_Equal: { + const Expr *Target = OE->getArg(0); + const Expr *Source = OE->getArg(1); + checkAccess(Target, AK_Written); + checkAccess(Source, AK_Read); + break; + } + default: { + const Expr *Source = OE->getArg(0); + checkAccess(Source, AK_Read); + break; + } + } + } + } NamedDecl *D = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl()); if(!D || !D->hasAttrs()) return; @@ -2063,6 +2100,13 @@ void BuildLockset::VisitCallExpr(CallExpr *Exp) { } void BuildLockset::VisitCXXConstructExpr(CXXConstructExpr *Exp) { + if (Analyzer->Handler.issueBetaWarnings()) { + const CXXConstructorDecl *D = Exp->getConstructor(); + if (D && D->isCopyConstructor()) { + const Expr* Source = Exp->getArg(0); + checkAccess(Source, AK_Read); + } + } // FIXME -- only handles constructors in DeclStmt below. } |