Charusso created this revision.
Charusso added a reviewer: NoQ.
Charusso added a project: clang.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, Szelethus, 
mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun.
Charusso retitled this revision from "[analyzer] DynamicTypeInfo: Simplify the 
API." to "[analyzer] DynamicTypeInfo: Simplify the API".
Charusso added a child revision: D67079: [analyzer] CastValueChecker: Model 
inheritance.

`DynamicTypeInfo` -> `const DynamicTypeInfo *`,
which removes the method `bool isValid()`.


Repository:
  rC Clang

https://reviews.llvm.org/D68199

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
  clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
  clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
  clang/lib/StaticAnalyzer/Core/CallEvent.cpp
  clang/lib/StaticAnalyzer/Core/DynamicType.cpp

Index: clang/lib/StaticAnalyzer/Core/DynamicType.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/DynamicType.cpp
+++ clang/lib/StaticAnalyzer/Core/DynamicType.cpp
@@ -37,23 +37,26 @@
 namespace clang {
 namespace ento {
 
-DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR) {
-  MR = MR->StripCasts();
+static const MemRegion *getSimplifiedRegion(const MemRegion *MR) {
+  return MR->StripCasts();
+}
+
+const DynamicTypeInfo *getDynamicTypeInfo(ProgramStateRef State,
+                                          const MemRegion *MR) {
+  MR = getSimplifiedRegion(MR);
 
   // Look up the dynamic type in the GDM.
   if (const DynamicTypeInfo *DTI = State->get<DynamicTypeMap>(MR))
-    return *DTI;
+    return DTI;
 
   // Otherwise, fall back to what we know about the region.
   if (const auto *TR = dyn_cast<TypedRegion>(MR))
-    return DynamicTypeInfo(TR->getLocationType(), /*CanBeSub=*/false);
+    return new DynamicTypeInfo(TR->getLocationType(), /*CanBeSub=*/false);
 
-  if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
-    SymbolRef Sym = SR->getSymbol();
-    return DynamicTypeInfo(Sym->getType());
-  }
+  if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
+    return new DynamicTypeInfo(SR->getSymbol()->getType());
 
-  return {};
+  return nullptr;
 }
 
 const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State,
@@ -77,15 +80,20 @@
 }
 
 ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR,
-                                   DynamicTypeInfo NewTy) {
-  State = State->set<DynamicTypeMap>(MR->StripCasts(), NewTy);
+                                   const DynamicTypeInfo *NewTy) {
+  assert((NewTy->getType()->isAnyPointerType() ||
+          NewTy->getType()->isReferenceType()) &&
+         "DynamicTypeInfo should always be a pointer.");
+  MR = getSimplifiedRegion(MR);
+  State = State->set<DynamicTypeMap>(MR, *NewTy);
   assert(State);
   return State;
 }
 
 ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR,
                                    QualType NewTy, bool CanBeSubClassed) {
-  return setDynamicTypeInfo(State, MR, DynamicTypeInfo(NewTy, CanBeSubClassed));
+  return setDynamicTypeInfo(State, MR,
+                            new DynamicTypeInfo(NewTy, CanBeSubClassed));
 }
 
 ProgramStateRef setDynamicTypeAndCastInfo(ProgramStateRef State,
@@ -154,7 +162,7 @@
     const DynamicTypeInfo &DTI = I->second;
     Indent(Out, Space, IsDot)
         << "{ \"region\": \"" << MR << "\", \"dyn_type\": ";
-    if (!DTI.isValid()) {
+    if (DTI.getType().isNull()) {
       Out << "null";
     } else {
       Out << '\"' << DTI.getType()->getPointeeType().getAsString()
Index: clang/lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -737,12 +737,12 @@
     return {};
 
   // Do we know anything about the type of 'this'?
-  DynamicTypeInfo DynType = getDynamicTypeInfo(getState(), R);
-  if (!DynType.isValid())
+  const DynamicTypeInfo *DynType = getDynamicTypeInfo(getState(), R);
+  if (!DynType)
     return {};
 
   // Is the type a C++ class? (This is mostly a defensive check.)
-  QualType RegionType = DynType.getType()->getPointeeType();
+  QualType RegionType = DynType->getType()->getPointeeType();
   assert(!RegionType.isNull() && "DynamicTypeInfo should always be a pointer.");
 
   const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
@@ -771,7 +771,7 @@
   // Does the decl that we found have an implementation?
   const FunctionDecl *Definition;
   if (!Result->hasBody(Definition)) {
-    if (!DynType.canBeASubClass())
+    if (!DynType->canBeASubClass())
       return AnyFunctionCall::getRuntimeDefinition();
     return {};
   }
@@ -779,7 +779,7 @@
   // We found a definition. If we're not sure that this devirtualization is
   // actually what will happen at runtime, make sure to provide the region so
   // that ExprEngine can decide what to do with it.
-  if (DynType.canBeASubClass())
+  if (DynType->canBeASubClass())
     return RuntimeDefinition(Definition, R->StripCasts());
   return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
 }
@@ -1208,15 +1208,15 @@
       if (!Receiver)
         return {};
 
-      DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
-      if (!DTI.isValid()) {
+      const DynamicTypeInfo *DTI = getDynamicTypeInfo(getState(), Receiver);
+      if (!DTI) {
         assert(isa<AllocaRegion>(Receiver) &&
                "Unhandled untyped region class!");
         return {};
       }
 
-      QualType DynType = DTI.getType();
-      CanBeSubClassed = DTI.canBeASubClass();
+      QualType DynType = DTI->getType();
+      CanBeSubClassed = DTI->canBeASubClass();
       ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
 
       if (ReceiverT && CanBeSubClassed)
Index: clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
@@ -1912,10 +1912,10 @@
 const CXXRecordDecl *getCXXRecordDecl(ProgramStateRef State,
                                       const MemRegion *Reg) {
   auto TI = getDynamicTypeInfo(State, Reg);
-  if (!TI.isValid())
+  if (!TI)
     return nullptr;
 
-  auto Type = TI.getType();
+  auto Type = TI->getType();
   if (const auto *RefT = Type->getAs<ReferenceType>()) {
     Type = RefT->getPointeeType();
   }
Index: clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -224,7 +224,7 @@
         const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
         if (!RecReg)
           return;
-        DynamicTypeInfo RecDynType = getDynamicTypeInfo(State, RecReg);
+        const DynamicTypeInfo *RecDynType = getDynamicTypeInfo(State, RecReg);
         C.addTransition(setDynamicTypeInfo(State, RetReg, RecDynType));
         break;
       }
@@ -351,10 +351,15 @@
       CastE->getType()->getAs<ObjCObjectPointerType>();
   if (!NewTy)
     return nullptr;
-  QualType OldDTy = getDynamicTypeInfo(C.getState(), ToR).getType();
+
+  QualType OldDTy;
+  if (const DynamicTypeInfo *DTI = getDynamicTypeInfo(C.getState(), ToR))
+    OldDTy = DTI->getType();
+
   if (OldDTy.isNull()) {
     return NewTy;
   }
+
   const ObjCObjectPointerType *OldTy =
     OldDTy->getAs<ObjCObjectPointerType>();
   if (!OldTy)
Index: clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
@@ -93,13 +93,12 @@
   ProgramStateRef State = N->getState();
   ProgramStateRef StatePrev = N->getFirstPred()->getState();
 
-  DynamicTypeInfo TrackedType = getDynamicTypeInfo(State, Reg);
-  DynamicTypeInfo TrackedTypePrev = getDynamicTypeInfo(StatePrev, Reg);
-  if (!TrackedType.isValid())
+  const DynamicTypeInfo *TrackedType = getDynamicTypeInfo(State, Reg);
+  const DynamicTypeInfo *TrackedTypePrev = getDynamicTypeInfo(StatePrev, Reg);
+  if (!TrackedType)
     return nullptr;
 
-  if (TrackedTypePrev.isValid() &&
-      TrackedTypePrev.getType() == TrackedType.getType())
+  if (TrackedTypePrev && TrackedTypePrev->getType() == TrackedType->getType())
     return nullptr;
 
   // Retrieve the associated statement.
@@ -112,7 +111,7 @@
   SmallString<256> Buf;
   llvm::raw_svector_ostream OS(Buf);
   OS << "Type '";
-  QualType::print(TrackedType.getType().getTypePtr(), Qualifiers(), OS,
+  QualType::print(TrackedType->getType().getTypePtr(), Qualifiers(), OS,
                   LangOpts, llvm::Twine());
   OS << "' is inferred from ";
 
@@ -162,12 +161,11 @@
     return;
 
   ProgramStateRef State = C.getState();
-  DynamicTypeInfo DynTypeInfo = getDynamicTypeInfo(State, Region);
-
-  if (!DynTypeInfo.isValid())
+  const DynamicTypeInfo *DynTypeInfo = getDynamicTypeInfo(State, Region);
+  if (!DynTypeInfo)
     return;
 
-  QualType DynType = DynTypeInfo.getType();
+  QualType DynType = DynTypeInfo->getType();
   QualType StaticType = CE->getType();
 
   const auto *DynObjCType = DynType->getAs<ObjCObjectPointerType>();
@@ -192,7 +190,7 @@
   if (ASTCtxt.canAssignObjCInterfaces(StaticObjCType, DynObjCType))
     return;
 
-  if (DynTypeInfo.canBeASubClass() &&
+  if (DynTypeInfo->canBeASubClass() &&
       ASTCtxt.canAssignObjCInterfaces(DynObjCType, StaticObjCType))
     return;
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
@@ -18,32 +18,29 @@
 /// of a region in a given state along the analysis path.
 class DynamicTypeInfo {
 public:
-  DynamicTypeInfo() : DynTy(QualType()) {}
+  DynamicTypeInfo() : Ty(QualType()) {}
 
-  DynamicTypeInfo(QualType Ty, bool CanBeSub = true)
-      : DynTy(Ty), CanBeASubClass(CanBeSub) {}
+  DynamicTypeInfo(QualType Ty, bool CanBeASubClass = true)
+      : Ty(Ty), CanBeASubClass(CanBeASubClass) {}
 
   /// Returns false if the type information is precise (the type 'DynTy' is
   /// the only type in the lattice), true otherwise.
   bool canBeASubClass() const { return CanBeASubClass; }
 
-  /// Returns true if the dynamic type info is available.
-  bool isValid() const { return !DynTy.isNull(); }
-
   /// Returns the currently inferred upper bound on the runtime type.
-  QualType getType() const { return DynTy; }
+  QualType getType() const { return Ty; }
 
   bool operator==(const DynamicTypeInfo &RHS) const {
-    return DynTy == RHS.DynTy && CanBeASubClass == RHS.CanBeASubClass;
+    return Ty == RHS.Ty && CanBeASubClass == RHS.CanBeASubClass;
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    ID.Add(DynTy);
+    ID.Add(Ty);
     ID.AddBoolean(CanBeASubClass);
   }
 
 private:
-  QualType DynTy;
+  QualType Ty;
   bool CanBeASubClass;
 };
 
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
@@ -30,7 +30,8 @@
 namespace ento {
 
 /// Get dynamic type information for the region \p MR.
-DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR);
+const DynamicTypeInfo *getDynamicTypeInfo(ProgramStateRef State,
+                                          const MemRegion *MR);
 
 /// Get raw dynamic type information for the region \p MR.
 const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State,
@@ -44,7 +45,7 @@
 
 /// Set dynamic type information of the region; return the new state.
 ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR,
-                                   DynamicTypeInfo NewTy);
+                                   const DynamicTypeInfo *NewTy);
 
 /// Set dynamic type information of the region; return the new state.
 ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to