summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2013-11-05 23:09:56 +0000
committerDeLesley Hutchins <delesley@google.com>2013-11-05 23:09:56 +0000
commit5ede5cc9ba0293bf0764e83cc264c40920bf1d7d (patch)
tree3b3a193abaaf80e3ecb226fe90aa173ba7a5d63c /clang
parent6664df12fb65100bd3643a56b30f63eb27c6b509 (diff)
downloadbcm5719-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.cpp8
-rw-r--r--clang/test/SemaCXX/warn-thread-safety-analysis.cpp84
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
+
OpenPOWER on IntegriCloud