[cfe-commits] r161264 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h lib/StaticAnalyzer/Core/ExprEngineC.cpp lib/StaticAnalyzer/Core/ProgramState.cpp test/Analysis/inlining/InlineObjCInstanceMethod.m

Anna Zaks ganna at apple.com
Fri Aug 3 14:43:37 PDT 2012


Author: zaks
Date: Fri Aug  3 16:43:37 2012
New Revision: 161264

URL: http://llvm.org/viewvc/llvm-project?rev=161264&view=rev
Log:
[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];

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
    cfe/trunk/test/Analysis/inlining/InlineObjCInstanceMethod.m

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=161264&r1=161263&r2=161264&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Fri Aug  3 16:43:37 2012
@@ -66,6 +66,12 @@
   DynamicTypeInfo() : T(QualType()) {}
   DynamicTypeInfo(QualType WithType) : T(WithType) {}
   QualType getType() {return T;}
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    T.Profile(ID);
+  }
+  bool operator==(const DynamicTypeInfo &X) const {
+    return T == X.T;
+  }
 };
 
 /// \class ProgramState
@@ -327,6 +333,8 @@
 
   /// Get dynamic type information for a region.
   DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const;
+  /// Add dynamic type information to the region and return the new state.
+  ProgramStateRef addDynamicTypeInfo(const MemRegion *Reg, QualType NewTy)const;
 
   //==---------------------------------------------------------------------==//
   // Accessing the Generic Data Map (GDM).

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=161264&r1=161263&r2=161264&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Fri Aug  3 16:43:37 2012
@@ -308,6 +308,9 @@
         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;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=161264&r1=161263&r2=161264&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Fri Aug  3 16:43:37 2012
@@ -732,11 +732,70 @@
   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;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Modified: cfe/trunk/test/Analysis/inlining/InlineObjCInstanceMethod.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/InlineObjCInstanceMethod.m?rev=161264&r1=161263&r2=161264&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/InlineObjCInstanceMethod.m (original)
+++ cfe/trunk/test/Analysis/inlining/InlineObjCInstanceMethod.m Fri Aug  3 16:43:37 2012
@@ -20,10 +20,10 @@
   return 5/y; // expected-warning {{Division by zero}}
 }
 
-// Method is called on inited object.
+// Get the dynamic type info from a cast (from id to MyClass*).
 + (int)testAllocInit {
   MyClass *a = [[self alloc] init];
-  return 5/[a getInt]; // todo
+  return 5/[a getInt]; // expected-warning {{Division by zero}}
 }
 
 // Method is called on inited object.





More information about the cfe-commits mailing list