r194103 - Thread safety analysis: check pt_guarded_by attribute when calling -> and *

DeLesley Hutchins delesley at google.com
Tue Nov 5 15:09:57 PST 2013


Author: delesley
Date: Tue Nov  5 17:09:56 2013
New Revision: 194103

URL: http://llvm.org/viewvc/llvm-project?rev=194103&view=rev
Log:
Thread safety analysis: check pt_guarded_by attribute when calling -> and *
on smart pointers.  -Wthread-safety-beta only.

Modified:
    cfe/trunk/lib/Analysis/ThreadSafety.cpp
    cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp

Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=194103&r1=194102&r2=194103&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Tue Nov  5 17:09:56 2013
@@ -2134,6 +2134,14 @@ void BuildLockset::VisitCallExpr(CallExp
         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);

Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp?rev=194103&r1=194102&r2=194103&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp Tue Nov  5 17:09:56 2013
@@ -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
+





More information about the cfe-commits mailing list