diff options
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 15 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 14 |
2 files changed, 23 insertions, 6 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 0a40b577cdc..6e0e1732bae 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -266,6 +266,11 @@ private: return NodeVec.size()-1; } + inline bool isCalleeArrow(const Expr *E) { + const MemberExpr *ME = dyn_cast<MemberExpr>(E->IgnoreParenCasts()); + return ME ? ME->isArrow() : false; + } + /// Build an SExpr from the given C++ expression. /// Recursive function that terminates on DeclRefExpr. /// Note: this function merely creates a SExpr; it does not check to @@ -327,8 +332,7 @@ private: if (LockReturnedAttr* At = MD->getAttr<LockReturnedAttr>()) { CallingContext LRCallCtx(CMCE->getMethodDecl()); LRCallCtx.SelfArg = CMCE->getImplicitObjectArgument(); - LRCallCtx.SelfArrow = - dyn_cast<MemberExpr>(CMCE->getCallee())->isArrow(); + LRCallCtx.SelfArrow = isCalleeArrow(CMCE->getCallee()); LRCallCtx.NumArgs = CMCE->getNumArgs(); LRCallCtx.FunArgs = CMCE->getArgs(); LRCallCtx.PrevCtx = CallCtx; @@ -338,7 +342,7 @@ private: // ignore any method named get(). if (CMCE->getMethodDecl()->getNameAsString() == "get" && CMCE->getNumArgs() == 0) { - if (NDeref && dyn_cast<MemberExpr>(CMCE->getCallee())->isArrow()) + if (NDeref && isCalleeArrow(CMCE->getCallee())) ++(*NDeref); return buildSExpr(CMCE->getImplicitObjectArgument(), CallCtx, NDeref); } @@ -496,11 +500,10 @@ private: } else if (const CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) { CallCtx.SelfArg = CE->getImplicitObjectArgument(); - CallCtx.SelfArrow = dyn_cast<MemberExpr>(CE->getCallee())->isArrow(); + CallCtx.SelfArrow = isCalleeArrow(CE->getCallee()); CallCtx.NumArgs = CE->getNumArgs(); CallCtx.FunArgs = CE->getArgs(); - } else if (const CallExpr *CE = - dyn_cast<CallExpr>(DeclExp)) { + } else if (const CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) { CallCtx.NumArgs = CE->getNumArgs(); CallCtx.FunArgs = CE->getArgs(); } else if (const CXXConstructExpr *CE = diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 8ed5466245a..ce6250d6da9 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -4300,3 +4300,17 @@ class SmartPtr_PtGuardedBy_Test { } // end namespace PtGuardedByTest + +namespace NonMemberCalleeICETest { + +class A { + void Run() { + (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires exclusive lock on 'M'}} + } + + void RunHelper() __attribute__((exclusive_locks_required(M))); + Mutex M; +}; + +} // end namespace NonMemberCalleeICETest + |