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 added a parent revision: D69599: [analyzer] DynamicSize: Remove 
'getSizeInElements()' from store.
Charusso added a comment.

@NoQ, I hope this is what you have suggested.


-


Repository:
  rC Clang

https://reviews.llvm.org/D69642

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
  clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
  clang/lib/StaticAnalyzer/Core/DynamicSize.cpp

Index: clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
+++ clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
@@ -18,11 +18,17 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
 
+REGISTER_MAP_WITH_PROGRAMSTATE(DynamicSizeMap, const clang::ento::MemRegion *,
+                               clang::ento::DefinedOrUnknownSVal)
+
 namespace clang {
 namespace ento {
 
 DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
                                     SValBuilder &SVB) {
+  if (const DefinedOrUnknownSVal *Size = State->get<DynamicSizeMap>(MR))
+    return *Size;
+
   return MR->getMemRegionManager().getStaticSize(MR, SVB);
 }
 
@@ -47,5 +53,30 @@
   return SVB.makeIntVal(RegionSize / ElementSize, SVB.getArrayIndexType());
 }
 
+ProgramStateRef setDynamicSizeAssumption(ProgramStateRef State,
+                                         const MemRegion *MR, SValBuilder &SVB,
+                                         DefinedOrUnknownSVal Size) {
+  DefinedOrUnknownSVal DynSize = getDynamicSize(State, MR, SVB);
+
+  if ((State = State->assume(SVB.evalEQ(State, DynSize, Size), true)))
+    State = State->set<DynamicSizeMap>(MR, Size);
+
+  return State;
+}
+
+std::pair<ProgramStateRef, ProgramStateRef>
+setDynamicSizeDualAssumption(ProgramStateRef State, const MemRegion *MR,
+                             SValBuilder &SVB, DefinedOrUnknownSVal Size) {
+  DefinedOrUnknownSVal DynSize = getDynamicSize(State, MR, SVB);
+
+  ProgramStateRef StateEQ, StateNE;
+  std::tie(StateEQ, StateNE) = State->assume(SVB.evalEQ(State, DynSize, Size));
+
+  if (StateEQ)
+    StateEQ = StateEQ->set<DynamicSizeMap>(MR, Size);
+
+  return {StateEQ, StateNE};
+}
+
 } // namespace ento
 } // namespace clang
Index: clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -168,13 +168,8 @@
 
   // Finally, assume that the array's size matches the given size.
   const LocationContext *LC = C.getLocationContext();
-  DefinedOrUnknownSVal DynSize =
-      getDynamicSize(state, state->getRegion(VD, LC), svalBuilder);
-
-  DefinedOrUnknownSVal ArraySize = ArraySizeVal.castAs<DefinedOrUnknownSVal>();
-  DefinedOrUnknownSVal sizeIsKnown =
-      svalBuilder.evalEQ(state, DynSize, ArraySize);
-  state = state->assume(sizeIsKnown, true);
+  state = setDynamicSizeAssumption(state, state->getRegion(VD, LC), svalBuilder,
+                                   ArraySizeVal.castAs<DefinedOrUnknownSVal>());
 
   // Assume should not fail at this point.
   assert(state);
Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1403,16 +1403,14 @@
   CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
 
   if (ElementCount.getAs<NonLoc>()) {
-    DefinedOrUnknownSVal DynSize = getDynamicSize(State, Region, svalBuilder);
-
     // size in Bytes = ElementCount*TypeSize
     SVal SizeInBytes = svalBuilder.evalBinOpNN(
         State, BO_Mul, ElementCount.castAs<NonLoc>(),
         svalBuilder.makeArrayIndex(TypeSize.getQuantity()),
         svalBuilder.getArrayIndexType());
-    DefinedOrUnknownSVal DynSizeMatchesSize = svalBuilder.evalEQ(
-        State, DynSize, SizeInBytes.castAs<DefinedOrUnknownSVal>());
-    State = State->assume(DynSizeMatchesSize, true);
+
+    State = setDynamicSizeAssumption(
+        State, Region, svalBuilder, SizeInBytes.castAs<DefinedOrUnknownSVal>());
   }
   return State;
 }
@@ -1541,13 +1539,7 @@
     return nullptr;
   if (Optional<DefinedOrUnknownSVal> DefinedSize =
           Size.getAs<DefinedOrUnknownSVal>()) {
-    DefinedOrUnknownSVal DynSize = getDynamicSize(State, R, svalBuilder);
-
-    DefinedOrUnknownSVal DynSizeMatchesSize =
-        svalBuilder.evalEQ(State, DynSize, *DefinedSize);
-
-    State = State->assume(DynSizeMatchesSize, true);
-    assert(State);
+    State = setDynamicSizeAssumption(State, R, svalBuilder, *DefinedSize);
   }
 
   return MallocUpdateRefState(C, CE, State, Family);
Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -1067,12 +1067,9 @@
   // For now we can only handle the case of offset is 0 and concrete char value.
   if (Offset.isValid() && !Offset.hasSymbolicOffset() &&
       Offset.getOffset() == 0) {
-    // Get the base region's size.
-    DefinedOrUnknownSVal SizeDV = getDynamicSize(State, BR, svalBuilder);
-
     ProgramStateRef StateWholeReg, StateNotWholeReg;
     std::tie(StateWholeReg, StateNotWholeReg) =
-        State->assume(svalBuilder.evalEQ(State, SizeDV, *SizeNL));
+        setDynamicSizeDualAssumption(State, BR, svalBuilder, *SizeNL);
 
     // With the semantic of 'memset()', we should convert the CharVal to
     // unsigned char.
Index: clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -91,10 +91,8 @@
       return true; // Return true to model purity.
 
     SValBuilder& svalBuilder = C.getSValBuilder();
-    DefinedOrUnknownSVal DynSize = getDynamicSize(state, R, svalBuilder);
-    DefinedOrUnknownSVal DynSizeMatchesSizeArg =
-        svalBuilder.evalEQ(state, DynSize, Size.castAs<DefinedOrUnknownSVal>());
-    state = state->assume(DynSizeMatchesSizeArg, true);
+    state = setDynamicSizeAssumption(state, R, svalBuilder,
+                                     Size.castAs<DefinedOrUnknownSVal>());
     assert(state && "The region should not have any previous constraints");
 
     C.addTransition(state->BindExpr(CE, LCtx, loc::MemRegionVal(R)));
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
@@ -22,16 +22,28 @@
 namespace clang {
 namespace ento {
 
-/// Get the stored dynamic size for the region \p MR.
+/// \returns The stored dynamic size for the region \p MR.
 DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
                                     SValBuilder &SVB);
 
-/// Get the stored element count of the region \p MR.
+/// \returns The stored element count of the region \p MR.
 DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
                                             const MemRegion *MR,
                                             SValBuilder &SVB,
                                             QualType ElementTy);
 
+/// Set the dynamic size \p Size of the region \p MR.
+/// \returns The assumption of the current dynamic size equal to \p Size.
+ProgramStateRef setDynamicSizeAssumption(ProgramStateRef State,
+                                         const MemRegion *MR, SValBuilder &SVB,
+                                         DefinedOrUnknownSVal Size);
+
+/// Set the dynamic size \p Size of the region \p MR.
+/// \returns The dual assumption of the current dynamic size equal to \p Size.
+std::pair<ProgramStateRef, ProgramStateRef>
+setDynamicSizeDualAssumption(ProgramStateRef State, const MemRegion *MR,
+                             SValBuilder &SVB, DefinedOrUnknownSVal Size);
+
 } // namespace ento
 } // namespace clang
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to