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 | f489d2b86c21246bf045083be3f1a25b7391f83d (patch) | |
tree | f9f43b1d8e7a87e7f020b4b47ff79b5b3556d6ee /clang/lib/Analysis/ThreadSafety.cpp | |
parent | 25dd07c112e94b58949a59407d31d8c7a369b0f8 (diff) | |
download | bcm5719-llvm-f489d2b86c21246bf045083be3f1a25b7391f83d.tar.gz bcm5719-llvm-f489d2b86c21246bf045083be3f1a25b7391f83d.zip |
Thread-safety analysis: check locks on method calls, operator=, and
copy constructors.
llvm-svn: 169350
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index bc3f85c7b5f..fdfd599ba52 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/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. } |