summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
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
commit150843b87ebd43a06d144cda8f74ee58c15ff46a (patch)
tree48921fc3b7da70cde89fe1b8517830f67c5c0072 /clang/lib/StaticAnalyzer
parent871701c606dc44eb2c42694b72351b9d59c10876 (diff)
downloadbcm5719-llvm-150843b87ebd43a06d144cda8f74ee58c15ff46a.tar.gz
bcm5719-llvm-150843b87ebd43a06d144cda8f74ee58c15ff46a.zip
[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]; llvm-svn: 161264
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Core/ProgramState.cpp65
2 files changed, 65 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 7ec151ef6d7..740dec5ec41 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -308,6 +308,9 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
const LocationContext *LCtx = Pred->getLocationContext();
SVal V = state->getSVal(Ex, LCtx);
V = svalBuilder.evalCast(V, T, ExTy);
+ if (const MemRegion *R = V.getAsRegion()) {
+ state = state->addDynamicTypeInfo(R, T);
+ }
state = state->BindExpr(CastE, LCtx, V);
Bldr.generateNode(CastE, Pred, state);
continue;
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
index 20f1e226b87..5730bc985ad 100644
--- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/clang/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;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
OpenPOWER on IntegriCloud