RedDocMD updated this revision to Diff 350362.
RedDocMD added a comment.

Made stylistic refactors


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103750/new/

https://reviews.llvm.org/D103750

Files:
  clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp

Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -35,9 +35,15 @@
 using namespace ento;
 
 namespace {
+
+enum class MakeUniqueKind {
+  Regular,      // ie, std::make_unique
+  ForOverwrite, // ie, std::make_unique_for_overwrite
+};
+
 class SmartPtrModeling
     : public Checker<eval::Call, check::DeadSymbols, check::RegionChanges,
-                     check::LiveSymbols> {
+                     check::LiveSymbols, check::Bind> {
 
   bool isBoolConversionMethod(const CallEvent &Call) const;
 
@@ -56,6 +62,7 @@
   void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
                   const char *Sep) const override;
   void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const;
+  void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
 
 private:
   void handleReset(const CallEvent &Call, CheckerContext &C) const;
@@ -76,10 +83,27 @@
       {{"release"}, &SmartPtrModeling::handleRelease},
       {{"swap", 1}, &SmartPtrModeling::handleSwap},
       {{"get"}, &SmartPtrModeling::handleGet}};
+  const CallDescription StdMakeUniqueCall{{"std", "make_unique"}};
+  const CallDescription StdMakeUniqueForOverwriteCall{
+      {"std", "make_unique_for_overwrite"}};
 };
 } // end of anonymous namespace
 
+class MakeUniqueKindWrapper {
+  const MakeUniqueKind Kind;
+
+public:
+  MakeUniqueKindWrapper(MakeUniqueKind Kind) : Kind(Kind) {}
+  MakeUniqueKind get() const { return Kind; }
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(static_cast<int>(Kind));
+  }
+  bool operator==(const MakeUniqueKind &RHS) const { return Kind == RHS; }
+  bool operator!=(const MakeUniqueKind &RHS) const { return Kind != RHS; }
+};
+
 REGISTER_MAP_WITH_PROGRAMSTATE(TrackedRegionMap, const MemRegion *, SVal)
+REGISTER_LIST_WITH_PROGRAMSTATE(MakeUniqueKindList, MakeUniqueKindWrapper)
 
 // Define the inter-checker API.
 namespace clang {
@@ -177,7 +201,21 @@
 
 bool SmartPtrModeling::evalCall(const CallEvent &Call,
                                 CheckerContext &C) const {
+
   ProgramStateRef State = C.getState();
+
+  if (Call.isCalled(StdMakeUniqueCall)) {
+    State = State->add<MakeUniqueKindList>(MakeUniqueKind::Regular);
+    C.addTransition(State);
+    return true;
+  }
+
+  if (Call.isCalled(StdMakeUniqueForOverwriteCall)) {
+    State = State->add<MakeUniqueKindList>(MakeUniqueKind::ForOverwrite);
+    C.addTransition(State);
+    return true;
+  }
+
   if (!smartptr::isStdSmartPtrCall(Call))
     return false;
 
@@ -272,6 +310,46 @@
   return C.isDifferent();
 }
 
+bool isUniquePtrType(QualType QT) {
+  if (QT.isNull())
+    return false;
+  const auto *Decl = QT->getAsCXXRecordDecl();
+  if (!Decl || !Decl->getDeclContext()->isStdNamespace())
+    return false;
+  const IdentifierInfo *ID = Decl->getIdentifier();
+  if (!ID)
+    return false;
+  const StringRef Name = ID->getName();
+  return Name == "unique_ptr";
+}
+
+void SmartPtrModeling::checkBind(SVal L, SVal V, const Stmt *S,
+                                 CheckerContext &C) const {
+  const auto *TVR = dyn_cast_or_null<TypedValueRegion>(L.getAsRegion());
+  if (!TVR)
+    return;
+  if (!isUniquePtrType(TVR->getValueType()))
+    return;
+  const auto *ThisRegion = dyn_cast<MemRegion>(TVR);
+  if (!ThisRegion)
+    return;
+
+  ProgramStateRef State = C.getState();
+  auto KindList = State->get<MakeUniqueKindList>();
+  assert(!KindList.isEmpty() &&
+         "Expected list to contain the kind of the last make_unique");
+  auto Kind = KindList.getHead();
+  if (Kind == MakeUniqueKind::ForOverwrite) {
+    auto RHSVal = C.getSValBuilder().makeNull();
+    State = State->set<TrackedRegionMap>(ThisRegion, RHSVal);
+  } else {
+    // TODO: Encode information that the inner pointer for
+    // unique_ptr made by std::make_unique is *not* null
+  }
+  State = State->set<MakeUniqueKindList>(KindList.getTail());
+  C.addTransition(State);
+}
+
 void SmartPtrModeling::checkDeadSymbols(SymbolReaper &SymReaper,
                                         CheckerContext &C) const {
   ProgramStateRef State = C.getState();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to