From: DeLesley Hutchins Date: Mon, 23 Apr 2012 18:39:55 +0000 (+0000) Subject: Thread safety analysis: support the use of pt_guarded_by attributes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aed9ea398a3fd8d488120728e2df4ac81c3b0c4b;p=clang Thread safety analysis: support the use of pt_guarded_by attributes on smart pointers. Also adds test case for previous commit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155379 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 27980bd541..59c4373190 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -238,6 +238,24 @@ static bool isIntOrBool(Expr *Exp) { return QT->isBooleanType() || QT->isIntegerType(); } + +// 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()) { + 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; +} + /// /// \brief Check if passed in Decl is a pointer type. /// Note that this function may produce an error message. @@ -249,6 +267,10 @@ static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D, QualType QT = vd->getType(); if (QT->isAnyPointerType()) return true; + + if (threadSafetyCheckIsSmartPointer(S, QT)) + return true; + S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << Attr.getName()->getName() << QT; } else { diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp index ac7737d4ac..af02be1430 100644 --- a/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -1343,6 +1343,10 @@ class Foo { namespace PointerToMemberTest { +// Empty string should be ignored. +int testEmptyAttribute GUARDED_BY(""); +void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED(""); + class Graph { public: Mu mu_; @@ -1356,5 +1360,31 @@ public: } + +namespace SmartPointerTest { + +template +class smart_ptr { + public: + smart_ptr(T* p) : ptr_(p) { }; + + T* operator->() { return ptr_; } + T& operator*() { return ptr_; } + + private: + T* ptr_; +}; + + +class MyClass { +public: + Mu mu_; + + smart_ptr a PT_GUARDED_BY(mu_); +}; + +} + + } // end namespace TestMultiDecl