diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-05-25 23:57:29 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-05-25 23:57:29 +0000 |
commit | e5cfd52a3a5d4bb46f77323fa8fa0b973fcde7bc (patch) | |
tree | 02a63c700337cf10575e51ed7f98aa89b651e6bc /lib | |
parent | 82713174914bdb927a254c5ee188e35fd79c4948 (diff) |
static analyzer: when conservatively evaluating functions, don't invalidate the values of globals when the called function is strlen.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132100 91177308-0d34-0410-b5e6-96231b3b80d8
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 = |