summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2012-12-05 01:20:45 +0000
committerDeLesley Hutchins <delesley@google.com>2012-12-05 01:20:45 +0000
commitf489d2b86c21246bf045083be3f1a25b7391f83d (patch)
treef9f43b1d8e7a87e7f020b4b47ff79b5b3556d6ee /clang/lib/Analysis/ThreadSafety.cpp
parent25dd07c112e94b58949a59407d31d8c7a369b0f8 (diff)
downloadbcm5719-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.cpp44
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.
}
OpenPOWER on IntegriCloud