[cfe-commits] r156030 - in /cfe/trunk: lib/Sema/SemaDeclAttr.cpp test/SemaCXX/warn-thread-safety-parsing.cpp

DeLesley Hutchins delesley at google.com
Wed May 2 15:18:42 PDT 2012


Author: delesley
Date: Wed May  2 17:18:42 2012
New Revision: 156030

URL: http://llvm.org/viewvc/llvm-project?rev=156030&view=rev
Log:
Thread safety analysis: additional support for smart pointers in lock expressions.

Modified:
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=156030&r1=156029&r2=156030&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed May  2 17:18:42 2012
@@ -241,26 +241,23 @@
 
 // Check to see if the type is a smart pointer of some kind.  We assume
 // it's a smart pointer if it defines both operator-> and operator*.
-static bool threadSafetyCheckIsSmartPointer(Sema &S, const QualType QT) {
-  if (const RecordType *RT = QT->getAs<RecordType>()) {
-    DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
-      S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
-    if (Res1.first == Res1.second)
-      return false;
+static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
+  DeclContextLookupConstResult Res1 = RT->getDecl()->lookup(
+    S.Context.DeclarationNames.getCXXOperatorName(OO_Star));
+  if (Res1.first == Res1.second)
+    return false;
 
-    DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
-      S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
-    if (Res2.first != Res2.second)
-      return true;
-  }
-  return false;
+  DeclContextLookupConstResult Res2 = RT->getDecl()->lookup(
+    S.Context.DeclarationNames.getCXXOperatorName(OO_Arrow));
+  if (Res2.first == Res2.second)
+    return false;
+
+  return true;
 }
 
-///
 /// \brief Check if passed in Decl is a pointer type.
 /// Note that this function may produce an error message.
 /// \return true if the Decl is a pointer type; false otherwise
-///
 static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
                                        const AttributeList &Attr) {
   if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
@@ -268,8 +265,16 @@
     if (QT->isAnyPointerType())
       return true;
 
-    if (threadSafetyCheckIsSmartPointer(S, QT))
-      return true;
+    if (const RecordType *RT = QT->getAs<RecordType>()) {
+      // If it's an incomplete type, it could be a smart pointer; skip it.
+      // (We don't want to force template instantiation if we can avoid it,
+      // since that would alter the order in which templates are instantiated.)
+      if (RT->isIncompleteType())
+        return true;
+
+      if (threadSafetyCheckIsSmartPointer(S, RT))
+        return true;
+    }
 
     S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
       << Attr.getName()->getName() << QT;
@@ -305,9 +310,16 @@
       << Attr.getName() << Ty.getAsString();
     return;
   }
+
   // Don't check for lockable if the class hasn't been defined yet. 
   if (RT->isIncompleteType())
     return;
+
+  // Allow smart pointers to be used as lockable objects.
+  // FIXME -- Check the type that the smart pointer points to.
+  if (threadSafetyCheckIsSmartPointer(S, RT))
+    return;
+
   // Warn if the type is not lockable.
   if (!RT->getDecl()->getAttr<LockableAttr>()) {
     S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)

Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp?rev=156030&r1=156029&r2=156030&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp Wed May  2 17:18:42 2012
@@ -1368,8 +1368,6 @@
 template<class T>
 class smart_ptr {
  public:
-  smart_ptr(T* p) : ptr_(p) { };
-
   T* operator->() { return ptr_; }
   T& operator*()  { return ptr_; }
 
@@ -1378,11 +1376,18 @@
 };
 
 
+Mutex gmu;
+smart_ptr<int> gdat PT_GUARDED_BY(gmu);
+
+
 class MyClass {
 public:
   Mutex mu_;
+  smart_ptr<Mutex> smu_;
+
 
   smart_ptr<int> a PT_GUARDED_BY(mu_);
+  int b            GUARDED_BY(smu_);
 };
 
 }





More information about the cfe-commits mailing list