From 4702f162bf6682c2dd65628185a25475535d7729 Mon Sep 17 00:00:00 2001 From: DeLesley Hutchins Date: Tue, 26 Nov 2013 19:45:21 +0000 Subject: [PATCH] Thread safety analysis: fix ICE due to missing null check on dyn_cast. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195777 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ThreadSafety.cpp | 15 +++++++++------ test/SemaCXX/warn-thread-safety-analysis.cpp | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) 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 + -- 2.40.0