From: Bill Wendling Date: Sun, 1 Dec 2013 03:45:49 +0000 (+0000) Subject: Merging r195777: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4444446abb50f7b0314d82be0afa892f945cc9bc;p=clang Merging r195777: ------------------------------------------------------------------------ r195777 | delesley | 2013-11-26 11:45:21 -0800 (Tue, 26 Nov 2013) | 1 line Thread safety analysis: fix ICE due to missing null check on dyn_cast. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@196007 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index 0a40b577cd..6e0e1732ba 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -266,6 +266,11 @@ private: return NodeVec.size()-1; } + inline bool isCalleeArrow(const Expr *E) { + const MemberExpr *ME = dyn_cast(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()) { CallingContext LRCallCtx(CMCE->getMethodDecl()); LRCallCtx.SelfArg = CMCE->getImplicitObjectArgument(); - LRCallCtx.SelfArrow = - dyn_cast(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(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(DeclExp)) { CallCtx.SelfArg = CE->getImplicitObjectArgument(); - CallCtx.SelfArrow = dyn_cast(CE->getCallee())->isArrow(); + CallCtx.SelfArrow = isCalleeArrow(CE->getCallee()); CallCtx.NumArgs = CE->getNumArgs(); CallCtx.FunArgs = CE->getArgs(); - } else if (const CallExpr *CE = - dyn_cast(DeclExp)) { + } else if (const CallExpr *CE = dyn_cast(DeclExp)) { CallCtx.NumArgs = CE->getNumArgs(); CallCtx.FunArgs = CE->getArgs(); } else if (const CXXConstructExpr *CE = diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp index 8ed5466245..ce6250d6da 100644 --- a/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/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 +