aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-01-04 23:54:01 +0000
committerAnna Zaks <ganna@apple.com>2012-01-04 23:54:01 +0000
commiteb31a76d1cdaaf8874c549dc6bd964ff270d3822 (patch)
tree2431945856d47f0454cf15617fe52bd33e15b095 /lib/StaticAnalyzer/Core/RegionStore.cpp
parentf063a3b783e22effa7972d05830cee942b2499ce (diff)
[analyzer] Be less pessimistic about invalidation of global variables
as a result of a call. Problem: Global variables, which come in from system libraries should not be invalidated by all calls. Also, non-system globals should not be invalidated by system calls. Solution: The following solution to invalidation of globals seems flexible enough for taint (does not invalidate stdin) and should not lead to too many false positives. We split globals into 3 classes: * immutable - values are preserved by calls (unless the specific global is passed in as a parameter): A : Most system globals and const scalars * invalidated by functions defined in system headers: B: errno * invalidated by all other functions (note, these functions may in turn contain system calls): B: errno C: all other globals (which are not in A nor B) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147569 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp64
1 files changed, 47 insertions, 17 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 56ce0e13a9..a0d1bada24 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -20,6 +20,7 @@
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -235,11 +236,16 @@ public:
//===-------------------------------------------------------------------===//
// Binding values to regions.
//===-------------------------------------------------------------------===//
+ RegionBindings invalidateGlobalRegion(MemRegion::Kind K,
+ const Expr *Ex,
+ unsigned Count,
+ RegionBindings B,
+ InvalidatedRegions *Invalidated);
StoreRef invalidateRegions(Store store, ArrayRef<const MemRegion *> Regions,
const Expr *E, unsigned Count,
InvalidatedSymbols &IS,
- bool invalidateGlobals,
+ const CallOrObjCMessage *Call,
InvalidatedRegions *Invalidated);
public: // Made public for helper classes.
@@ -718,15 +724,39 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
B = RM.addBinding(B, baseR, BindingKey::Direct, V);
}
+RegionBindings RegionStoreManager::invalidateGlobalRegion(MemRegion::Kind K,
+ const Expr *Ex,
+ unsigned Count,
+ RegionBindings B,
+ InvalidatedRegions *Invalidated) {
+ // Bind the globals memory space to a new symbol that we will use to derive
+ // the bindings for all globals.
+ const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(K);
+ SVal V =
+ svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex,
+ /* symbol type, doesn't matter */ Ctx.IntTy,
+ Count);
+
+ B = removeBinding(B, GS);
+ B = addBinding(B, BindingKey::Make(GS, BindingKey::Default), V);
+
+ // Even if there are no bindings in the global scope, we still need to
+ // record that we touched it.
+ if (Invalidated)
+ Invalidated->push_back(GS);
+
+ return B;
+}
+
StoreRef RegionStoreManager::invalidateRegions(Store store,
ArrayRef<const MemRegion *> Regions,
const Expr *Ex, unsigned Count,
InvalidatedSymbols &IS,
- bool invalidateGlobals,
+ const CallOrObjCMessage *Call,
InvalidatedRegions *Invalidated) {
invalidateRegionsWorker W(*this, StateMgr,
RegionStoreManager::GetRegionBindings(store),
- Ex, Count, IS, Invalidated, invalidateGlobals);
+ Ex, Count, IS, Invalidated, false);
// Scan the bindings and generate the clusters.
W.GenerateClusters();
@@ -741,20 +771,20 @@ StoreRef RegionStoreManager::invalidateRegions(Store store,
// Return the new bindings.
RegionBindings B = W.getRegionBindings();
- if (invalidateGlobals) {
- // Bind the non-static globals memory space to a new symbol that we will
- // use to derive the bindings for all non-static globals.
- const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion();
- SVal V =
- svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, Ex,
- /* symbol type, doesn't matter */ Ctx.IntTy,
- Count);
- B = addBinding(B, BindingKey::Make(GS, BindingKey::Default), V);
-
- // Even if there are no bindings in the global scope, we still need to
- // record that we touched it.
- if (Invalidated)
- Invalidated->push_back(GS);
+ // For all globals which are not static nor immutable: determine which global
+ // regions should be invalidated and invalidate them.
+ // TODO: This could possibly be more precise with modules.
+ //
+ // System calls invalidate only system globals.
+ if (Call && Call->isInSystemHeader()) {
+ B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
+ Ex, Count, B, Invalidated);
+ // Internal calls might invalidate both system and internal globals.
+ } else {
+ B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
+ Ex, Count, B, Invalidated);
+ B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
+ Ex, Count, B, Invalidated);
}
return StoreRef(B.getRootWithoutRetain(), *this);