aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ProgramState.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-08-03 21:43:37 +0000
committerAnna Zaks <ganna@apple.com>2012-08-03 21:43:37 +0000
commit148fee988e32efcad45ecf7b3bf714880c657dda (patch)
tree0d51ee02bdc3957c1338ce25a091324e8cc150c4 /lib/StaticAnalyzer/Core/ProgramState.cpp
parent89ab7d0012ffe02a335b765eeb9b48977a5ecd79 (diff)
[analyzer] ObjC Inlining: Start tracking dynamic type info in the GDM
In the following code, find the type of the symbolic receiver by following it and updating the dynamic type info in the state when we cast the symbol from id to MyClass *. MyClass *a = [[self alloc] init]; return 5/[a testSelf]; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161264 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp65
1 files changed, 62 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 20f1e226b8..5730bc985a 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -732,11 +732,70 @@ bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const {
return Tainted;
}
+/// The GDM component containing the dynamic type info. This is a map from a
+/// symbol to it's most likely type.
+namespace clang {
+namespace ento {
+struct DynamicTypeMap {};
+typedef llvm::ImmutableMap<SymbolRef, DynamicTypeInfo> DynamicTypeMapImpl;
+template<> struct ProgramStateTrait<DynamicTypeMap>
+ : public ProgramStatePartialTrait<DynamicTypeMapImpl> {
+ static void *GDMIndex() { static int index; return &index; }
+};
+}}
+
DynamicTypeInfo ProgramState::getDynamicTypeInfo(const MemRegion *Reg) const {
if (const TypedRegion *TR = dyn_cast<TypedRegion>(Reg))
return DynamicTypeInfo(TR->getLocationType());
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg))
- return DynamicTypeInfo(SR->getSymbol()
- ->getType(getStateManager().getContext()));
+
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
+ SymbolRef Sym = SR->getSymbol();
+ // Lookup the dynamic type in the GDM.
+ const DynamicTypeInfo *GDMType = get<DynamicTypeMap>(Sym);
+ if (GDMType)
+ return *GDMType;
+
+ // Else, lookup the type at point of symbol creation.
+ return DynamicTypeInfo(Sym->getType(getStateManager().getContext()));
+ }
return DynamicTypeInfo();
}
+
+ProgramStateRef ProgramState::addDynamicTypeInfo(const MemRegion *Reg,
+ QualType NewTy) const {
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
+ SymbolRef Sym = SR->getSymbol();
+ // TODO: Instead of resetting the type info, check the old type info and
+ // merge and pick the most precise type.
+ ProgramStateRef NewState = set<DynamicTypeMap>(Sym, DynamicTypeInfo(NewTy));
+ assert(NewState);
+ return NewState;
+ }
+ return this;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+