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

Minimal modelling of destructor


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D105821

Files:
  clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
  clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp


Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -753,10 +753,13 @@
                                             *Call, *this);
 
   ExplodedNodeSet DstInvalidated;
-  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
-  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
-       I != E; ++I)
-    defaultEvalCall(Bldr, *I, *Call, CallOpts);
+  // StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
+  // for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E =
+  // DstPreCall.end();
+  //      I != E; ++I)
+  //   defaultEvalCall(Bldr, *I, *Call, CallOpts);
+  getCheckerManager().runCheckersForEvalCall(DstInvalidated, DstPreCall, *Call,
+                                             *this, CallOpts);
 
   getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
                                              *Call, *this);
Index: clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -664,14 +664,11 @@
     for (const auto &EvalCallChecker : EvalCallCheckers) {
       // TODO: Support the situation when the call doesn't correspond
       // to any Expr.
-      ProgramPoint L = ProgramPoint::getProgramPoint(
-          Call.getOriginExpr(), ProgramPoint::PostStmtKind,
-          Pred->getLocationContext(), EvalCallChecker.Checker);
       bool evaluated = false;
       { // CheckerContext generates transitions(populates checkDest) on
         // destruction, so introduce the scope to make sure it gets properly
         // populated.
-        CheckerContext C(B, Eng, Pred, L);
+        CheckerContext C(B, Eng, Pred, Call.getProgramPoint());
         evaluated = EvalCallChecker(Call, C);
       }
       assert(!(evaluated && anyEvaluated)
Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -269,6 +269,7 @@
                                 CheckerContext &C) const {
 
   ProgramStateRef State = C.getState();
+  Call.dump();
 
   // If any one of the arg is a unique_ptr, then
   // we can try this function
@@ -365,6 +366,18 @@
     }
   }
 
+  if (const auto *DC = dyn_cast<CXXDestructorCall>(&Call)) {
+    llvm::errs() << "Found destructor call\n";
+    const MemRegion *ThisRegion = DC->getCXXThisVal().getAsRegion();
+    assert(ThisRegion && "We do not support explicit calls to destructor");
+    const auto *InnerPtrVal = State->get<TrackedRegionMap>(ThisRegion);
+    State = State->remove<TrackedRegionMap>(ThisRegion);
+    State = State->invalidateRegions({*InnerPtrVal}, nullptr, C.blockCount(),
+                                     C.getLocationContext(), true);
+    C.addTransition(State);
+    return true;
+  }
+
   if (!ModelSmartPtrDereference)
     return false;
 


Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -753,10 +753,13 @@
                                             *Call, *this);
 
   ExplodedNodeSet DstInvalidated;
-  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
-  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
-       I != E; ++I)
-    defaultEvalCall(Bldr, *I, *Call, CallOpts);
+  // StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
+  // for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E =
+  // DstPreCall.end();
+  //      I != E; ++I)
+  //   defaultEvalCall(Bldr, *I, *Call, CallOpts);
+  getCheckerManager().runCheckersForEvalCall(DstInvalidated, DstPreCall, *Call,
+                                             *this, CallOpts);
 
   getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
                                              *Call, *this);
Index: clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ clang/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -664,14 +664,11 @@
     for (const auto &EvalCallChecker : EvalCallCheckers) {
       // TODO: Support the situation when the call doesn't correspond
       // to any Expr.
-      ProgramPoint L = ProgramPoint::getProgramPoint(
-          Call.getOriginExpr(), ProgramPoint::PostStmtKind,
-          Pred->getLocationContext(), EvalCallChecker.Checker);
       bool evaluated = false;
       { // CheckerContext generates transitions(populates checkDest) on
         // destruction, so introduce the scope to make sure it gets properly
         // populated.
-        CheckerContext C(B, Eng, Pred, L);
+        CheckerContext C(B, Eng, Pred, Call.getProgramPoint());
         evaluated = EvalCallChecker(Call, C);
       }
       assert(!(evaluated && anyEvaluated)
Index: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -269,6 +269,7 @@
                                 CheckerContext &C) const {
 
   ProgramStateRef State = C.getState();
+  Call.dump();
 
   // If any one of the arg is a unique_ptr, then
   // we can try this function
@@ -365,6 +366,18 @@
     }
   }
 
+  if (const auto *DC = dyn_cast<CXXDestructorCall>(&Call)) {
+    llvm::errs() << "Found destructor call\n";
+    const MemRegion *ThisRegion = DC->getCXXThisVal().getAsRegion();
+    assert(ThisRegion && "We do not support explicit calls to destructor");
+    const auto *InnerPtrVal = State->get<TrackedRegionMap>(ThisRegion);
+    State = State->remove<TrackedRegionMap>(ThisRegion);
+    State = State->invalidateRegions({*InnerPtrVal}, nullptr, C.blockCount(),
+                                     C.getLocationContext(), true);
+    C.addTransition(State);
+    return true;
+  }
+
   if (!ModelSmartPtrDereference)
     return false;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to