diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/Core/CFRefCount.cpp | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 21 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ObjCMessage.cpp | 7 |
3 files changed, 35 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/CFRefCount.cpp b/lib/StaticAnalyzer/Core/CFRefCount.cpp index 59fea1031f..013eeec0e4 100644 --- a/lib/StaticAnalyzer/Core/CFRefCount.cpp +++ b/lib/StaticAnalyzer/Core/CFRefCount.cpp @@ -2664,11 +2664,13 @@ void CFRefCount::evalSummary(ExplodedNodeSet& Dst, // NOTE: Even if RegionsToInvalidate is empty, we must still invalidate // global variables. // NOTE: RetainReleaseChecker handles the actual invalidation of symbols. - state = state->invalidateRegions(RegionsToInvalidate.data(), - RegionsToInvalidate.data() + - RegionsToInvalidate.size(), - Ex, Count, &IS, - /* invalidateGlobals = */ true); + state = + state->invalidateRegions(RegionsToInvalidate.data(), + RegionsToInvalidate.data() + + RegionsToInvalidate.size(), + Ex, Count, &IS, + /* invalidateGlobals = */ + Eng.doesInvalidateGlobals(callOrMsg)); // Evaluate the effect on the message receiver. if (!ErrorRange.isValid() && Receiver) { diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 4b7d999bd4..6fd66c1f31 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -156,6 +156,27 @@ const GRState* ExprEngine::getInitialState(const LocationContext *InitLoc) { return state; } +bool +ExprEngine::doesInvalidateGlobals(const CallOrObjCMessage &callOrMessage) const +{ + if (callOrMessage.isFunctionCall() && !callOrMessage.isCXXCall()) { + SVal calleeV = callOrMessage.getFunctionCallee(); + if (const FunctionTextRegion *codeR = + llvm::dyn_cast_or_null<FunctionTextRegion>(calleeV.getAsRegion())) { + + const FunctionDecl *fd = codeR->getDecl(); + if (const IdentifierInfo *ii = fd->getIdentifier()) { + llvm::StringRef fname = ii->getName(); + if (fname == "strlen") + return false; + } + } + } + + // The conservative answer: invalidates globals. + return true; +} + //===----------------------------------------------------------------------===// // Top-level transfer function logic (Dispatcher). //===----------------------------------------------------------------------===// diff --git a/lib/StaticAnalyzer/Core/ObjCMessage.cpp b/lib/StaticAnalyzer/Core/ObjCMessage.cpp index c005819c9c..c000600474 100644 --- a/lib/StaticAnalyzer/Core/ObjCMessage.cpp +++ b/lib/StaticAnalyzer/Core/ObjCMessage.cpp @@ -141,6 +141,13 @@ SVal CallOrObjCMessage::getArgSValAsScalarOrLoc(unsigned i) const { return UnknownVal(); } +SVal CallOrObjCMessage::getFunctionCallee() const { + assert(isFunctionCall()); + assert(!isCXXCall()); + const Expr *callee = CallE->getCallee()->IgnoreParenCasts(); + return State->getSVal(callee); +} + SVal CallOrObjCMessage::getCXXCallee() const { assert(isCXXCall()); const Expr *callee = |