diff options
author | DeLesley Hutchins <delesley@google.com> | 2013-11-05 23:09:56 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2013-11-05 23:09:56 +0000 |
commit | 5ede5cc9ba0293bf0764e83cc264c40920bf1d7d (patch) | |
tree | 3b3a193abaaf80e3ecb226fe90aa173ba7a5d63c /clang | |
parent | 6664df12fb65100bd3643a56b30f63eb27c6b509 (diff) | |
download | bcm5719-llvm-5ede5cc9ba0293bf0764e83cc264c40920bf1d7d.tar.gz bcm5719-llvm-5ede5cc9ba0293bf0764e83cc264c40920bf1d7d.zip |
Thread safety analysis: check pt_guarded_by attribute when calling -> and *
on smart pointers. -Wthread-safety-beta only.
llvm-svn: 194103
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 84 |
2 files changed, 92 insertions, 0 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index e5e5f18b515..607526db3e5 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2134,6 +2134,14 @@ void BuildLockset::VisitCallExpr(CallExpr *Exp) { checkAccess(Source, AK_Read); break; } + case OO_Star: + case OO_Arrow: { + if (Analyzer->Handler.issueBetaWarnings()) { + const Expr *Target = OE->getArg(0); + checkPtAccess(Target, AK_Read); + } + break; + } default: { const Expr *Source = OE->getArg(0); checkAccess(Source, AK_Read); diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 08c6f8582aa..8ea411325fb 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -4142,3 +4142,87 @@ public: } // end namespace LogicalConditionalTryLock + + +namespace PtGuardedByTest { + +void doSomething(); + +class Cell { + public: + int a; +}; + + +// This mainly duplicates earlier tests, but just to make sure... +class PtGuardedBySanityTest { + Mutex mu1; + Mutex mu2; + int* a GUARDED_BY(mu1) PT_GUARDED_BY(mu2); + Cell* c GUARDED_BY(mu1) PT_GUARDED_BY(mu2); + + void test1() { + mu1.Lock(); + if (a == 0) doSomething(); // OK, we don't dereference. + a = 0; + c = 0; + mu1.Unlock(); + } + + void test2() { + mu1.ReaderLock(); + if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}} + *a = 0; // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}} + + if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}} + c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}} + + if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}} + (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}} + mu1.Unlock(); + } + + void test3() { + mu2.Lock(); + if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires locking 'mu1'}} + *a = 0; // expected-warning {{reading variable 'a' requires locking 'mu1'}} + + if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}} + c->a = 0; // expected-warning {{reading variable 'c' requires locking 'mu1'}} + + if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}} + (*c).a = 0; // expected-warning {{reading variable 'c' requires locking 'mu1'}} + mu2.Unlock(); + } + + void test4() { + mu1.ReaderLock(); // OK -- correct use. + mu2.Lock(); + if (*a == 0) doSomething(); + *a = 0; + + if (c->a == 0) doSomething(); + c->a = 0; + + if ((*c).a == 0) doSomething(); + (*c).a = 0; + mu2.Unlock(); + mu1.Unlock(); + } +}; + + +class SmartPtr_PtGuardedBy_Test { + Mutex mu2; + SmartPtr<int> sp PT_GUARDED_BY(mu2); + SmartPtr<Cell> sq PT_GUARDED_BY(mu2); + + void test() { + sp.get(); // OK -- no GUARDED_BY + *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}} + sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}} + } +}; + +} // end namespace PtGuardedByTest + |