diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-05-04 16:28:38 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-05-04 16:28:38 +0000 |
commit | bbba25fa8e388e82e04f66784c2fc9f89b901abe (patch) | |
tree | 0f13046430de4cd285c12570d2406ce3abe79365 /lib/Sema/SemaDeclAttr.cpp | |
parent | 8775485350b2419cb9953518ace61cf68b1c9c18 (diff) |
Thread safety analysis: check for LOCKABLE attribute on base classes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156175 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 3706bb8c8c..ba1e69990f 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -14,6 +14,7 @@ #include "clang/Sema/SemaInternal.h" #include "TargetAttributesSema.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclObjC.h" @@ -298,6 +299,16 @@ static const RecordType *getRecordType(QualType QT) { return 0; } + +bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, void *UserData) { + const RecordType *RT = Specifier->getType()->getAs<RecordType>(); + if (RT->getDecl()->getAttr<LockableAttr>()) + return true; + return false; +} + + /// \brief Thread Safety Analysis: Checks that the passed in RecordType /// resolves to a lockable object. static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, @@ -320,12 +331,20 @@ static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 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) - << Attr.getName() << Ty.getAsString(); + // Check if the type is lockable. + RecordDecl *RD = RT->getDecl(); + if (RD->getAttr<LockableAttr>()) return; + + // Else check if any base classes are lockable. + if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { + CXXBasePaths BPaths(false, false); + if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths)) + return; } + + S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable) + << Attr.getName() << Ty.getAsString(); } /// \brief Thread Safety Analysis: Checks that all attribute arguments, starting |