aaronpuchert created this revision. aaronpuchert added reviewers: aaron.ballman, delesley, lukasza. Herald added a subscriber: cfe-commits.
This imitates the code for MemberExpr. I hope it is right, for I have absolutely no understanding of ObjC++. Fixes 38896. Repository: rC Clang https://reviews.llvm.org/D52200 Files: include/clang/Analysis/Analyses/ThreadSafetyCommon.h lib/Analysis/ThreadSafetyCommon.cpp test/SemaObjCXX/warn-thread-safety-analysis.mm Index: test/SemaObjCXX/warn-thread-safety-analysis.mm =================================================================== --- /dev/null +++ test/SemaObjCXX/warn-thread-safety-analysis.mm @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s + +class __attribute__((lockable)) Lock { +public: + void Acquire() __attribute__((exclusive_lock_function())) {} + void Release() __attribute__((unlock_function())) {} +}; + +class __attribute__((scoped_lockable)) AutoLock { +public: + AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock))) + : lock_(lock) { + lock.Acquire(); + } + ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); } + +private: + Lock &lock_; +}; + +@interface MyInterface { +@private + Lock lock_; + int value_; +} + +- (void)incrementValue; +- (void)decrementValue; + +@end + +@implementation MyInterface + +- (void)incrementValue { + AutoLock lock(lock_); + value_ += 1; +} + +- (void)decrementValue { + lock_.Acquire(); // expected-note{{mutex acquired here}} + value_ -= 1; +} // expected-warning{{mutex 'self.lock_' is still held at the end of function}} + +@end Index: lib/Analysis/ThreadSafetyCommon.cpp =================================================================== --- lib/Analysis/ThreadSafetyCommon.cpp +++ lib/Analysis/ThreadSafetyCommon.cpp @@ -211,6 +211,8 @@ return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx); case Stmt::MemberExprClass: return translateMemberExpr(cast<MemberExpr>(S), Ctx); + case Stmt::ObjCIvarRefExprClass: + return translateObjCIVarRefExpr(cast<ObjCIvarRefExpr>(S), Ctx); case Stmt::CallExprClass: return translateCallExpr(cast<CallExpr>(S), Ctx); case Stmt::CXXMemberCallExprClass: @@ -349,6 +351,19 @@ return P; } +til::SExpr *SExprBuilder::translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE, + CallingContext *Ctx) { + til::SExpr *BE = translate(IVRE->getBase(), Ctx); + til::SExpr *E = new (Arena) til::SApply(BE); + + const auto *D = cast<ObjCIvarDecl>(IVRE->getDecl()->getCanonicalDecl()); + + til::Project *P = new (Arena) til::Project(E, D); + if (hasCppPointerType(BE)) + P->setArrow(true); + return P; +} + til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE, CallingContext *Ctx, const Expr *SelfE) { Index: include/clang/Analysis/Analyses/ThreadSafetyCommon.h =================================================================== --- include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -397,6 +397,8 @@ CallingContext *Ctx) ; til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx); til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx); + til::SExpr *translateObjCIVarRefExpr(const ObjCIvarRefExpr *ME, + CallingContext *Ctx); til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx, const Expr *SelfE = nullptr); til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
Index: test/SemaObjCXX/warn-thread-safety-analysis.mm =================================================================== --- /dev/null +++ test/SemaObjCXX/warn-thread-safety-analysis.mm @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s + +class __attribute__((lockable)) Lock { +public: + void Acquire() __attribute__((exclusive_lock_function())) {} + void Release() __attribute__((unlock_function())) {} +}; + +class __attribute__((scoped_lockable)) AutoLock { +public: + AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock))) + : lock_(lock) { + lock.Acquire(); + } + ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); } + +private: + Lock &lock_; +}; + +@interface MyInterface { +@private + Lock lock_; + int value_; +} + +- (void)incrementValue; +- (void)decrementValue; + +@end + +@implementation MyInterface + +- (void)incrementValue { + AutoLock lock(lock_); + value_ += 1; +} + +- (void)decrementValue { + lock_.Acquire(); // expected-note{{mutex acquired here}} + value_ -= 1; +} // expected-warning{{mutex 'self.lock_' is still held at the end of function}} + +@end Index: lib/Analysis/ThreadSafetyCommon.cpp =================================================================== --- lib/Analysis/ThreadSafetyCommon.cpp +++ lib/Analysis/ThreadSafetyCommon.cpp @@ -211,6 +211,8 @@ return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx); case Stmt::MemberExprClass: return translateMemberExpr(cast<MemberExpr>(S), Ctx); + case Stmt::ObjCIvarRefExprClass: + return translateObjCIVarRefExpr(cast<ObjCIvarRefExpr>(S), Ctx); case Stmt::CallExprClass: return translateCallExpr(cast<CallExpr>(S), Ctx); case Stmt::CXXMemberCallExprClass: @@ -349,6 +351,19 @@ return P; } +til::SExpr *SExprBuilder::translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE, + CallingContext *Ctx) { + til::SExpr *BE = translate(IVRE->getBase(), Ctx); + til::SExpr *E = new (Arena) til::SApply(BE); + + const auto *D = cast<ObjCIvarDecl>(IVRE->getDecl()->getCanonicalDecl()); + + til::Project *P = new (Arena) til::Project(E, D); + if (hasCppPointerType(BE)) + P->setArrow(true); + return P; +} + til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE, CallingContext *Ctx, const Expr *SelfE) { Index: include/clang/Analysis/Analyses/ThreadSafetyCommon.h =================================================================== --- include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -397,6 +397,8 @@ CallingContext *Ctx) ; til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx); til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx); + til::SExpr *translateObjCIVarRefExpr(const ObjCIvarRefExpr *ME, + CallingContext *Ctx); til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx, const Expr *SelfE = nullptr); til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits