]> granicus.if.org Git - clang/commitdiff
Thread-safety analysis: support new "pointer to member" syntax for
authorDeLesley Hutchins <delesley@google.com>
Mon, 23 Apr 2012 16:45:01 +0000 (16:45 +0000)
committerDeLesley Hutchins <delesley@google.com>
Mon, 23 Apr 2012 16:45:01 +0000 (16:45 +0000)
existentially quantified lock expressions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155357 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclAttr.cpp
test/SemaCXX/warn-thread-safety-parsing.cpp

index 843d5a4731628c85aad2fff8431a0e758180d868..27980bd541f30401b294487641320dad9bfa8ea7 100644 (file)
@@ -313,7 +313,11 @@ static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
       continue;
     }
 
-    if (isa<StringLiteral>(ArgExp)) {
+    if (StringLiteral *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
+      // Ignore empty strings without warnings
+      if (StrLit->getLength() == 0)
+        continue;
+
       // We allow constant strings to be used as a placeholder for expressions
       // that are not valid C++ syntax, but warn that they are ignored.
       S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
@@ -323,6 +327,14 @@ static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
 
     QualType ArgTy = ArgExp->getType();
 
+    // A pointer to member expression of the form  &MyClass::mu is treated
+    // specially -- we need to look at the type of the member.
+    if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(ArgExp))
+      if (UOp->getOpcode() == UO_AddrOf)
+        if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
+          if (DRE->getDecl()->isCXXInstanceMember())
+            ArgTy = DRE->getDecl()->getType();
+
     // First see if we can just cast to record type, or point to record type.
     const RecordType *RT = getRecordType(ArgTy);
 
index a9e58dd87289193bf3ce9a515100f9034ccf6445..ac7737d4ac28d08fa1206eeb331ae1312e09d864 100644 (file)
@@ -1341,5 +1341,20 @@ class Foo {
 
 }
 
+namespace PointerToMemberTest {
+
+class Graph {
+public:
+  Mu mu_;
+};
+
+class Node {
+public:
+  void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_);
+  int a GUARDED_BY(&Graph::mu_);
+};
+
+}
+
 } // end namespace TestMultiDecl