aboutsummaryrefslogtreecommitdiff
path: root/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
commit91e2061763f5e59f57e59c6f141b74b5ff0408ad (patch)
treeadab0c157e492edfe63314b38eff46ba179218c0 /lib/Analysis/ThreadSafety.cpp
parent39a62fcd3003785d9cc913ab2820be2f6f27bb40 (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.cpp44
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.
}