This revision was automatically updated to reflect the committed changes.
Closed by commit rG601687bf731a: [analyzer] DynamicSize: Remove 
'getExtent()' from regions (authored by Charusso).

Changed prior to commit:
  https://reviews.llvm.org/D69540?vs=227013&id=241447#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69540

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
  clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
  clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
  clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
  clang/lib/StaticAnalyzer/Core/CMakeLists.txt
  clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
  clang/lib/StaticAnalyzer/Core/MemRegion.cpp
  clang/lib/StaticAnalyzer/Core/RegionStore.cpp
  clang/lib/StaticAnalyzer/Core/SymbolManager.cpp

Index: clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ clang/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -329,7 +329,7 @@
 }
 
 QualType SymbolExtent::getType() const {
-  ASTContext &Ctx = R->getMemRegionManager()->getContext();
+  ASTContext &Ctx = R->getMemRegionManager().getContext();
   return Ctx.getSizeType();
 }
 
Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
@@ -876,7 +877,7 @@
 
   // Find the length (in bits) of the region being invalidated.
   uint64_t Length = UINT64_MAX;
-  SVal Extent = Top->getExtent(SVB);
+  SVal Extent = Top->getMemRegionManager().getStaticSize(Top, SVB);
   if (Optional<nonloc::ConcreteInt> ExtentCI =
           Extent.getAs<nonloc::ConcreteInt>()) {
     const llvm::APSInt &ExtentInt = ExtentCI->getValue();
@@ -1394,7 +1395,7 @@
 RegionStoreManager::getSizeInElements(ProgramStateRef state,
                                       const MemRegion *R,
                                       QualType EleTy) {
-  SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
+  DefinedOrUnknownSVal Size = getDynamicSize(state, R, svalBuilder);
   const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
   if (!SizeInt)
     return UnknownVal();
Index: clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -142,7 +142,7 @@
   return false;
 }
 
-MemRegionManager* SubRegion::getMemRegionManager() const {
+MemRegionManager &SubRegion::getMemRegionManager() const {
   const SubRegion* r = this;
   do {
     const MemRegion *superRegion = r->getSuperRegion();
@@ -159,56 +159,6 @@
   return SSR ? SSR->getStackFrame() : nullptr;
 }
 
-//===----------------------------------------------------------------------===//
-// Region extents.
-//===----------------------------------------------------------------------===//
-
-DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
-  ASTContext &Ctx = svalBuilder.getContext();
-  QualType T = getDesugaredValueType(Ctx);
-
-  if (isa<VariableArrayType>(T))
-    return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
-  if (T->isIncompleteType())
-    return UnknownVal();
-
-  CharUnits size = Ctx.getTypeSizeInChars(T);
-  QualType sizeTy = svalBuilder.getArrayIndexType();
-  return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
-}
-
-DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
-  // Force callers to deal with bitfields explicitly.
-  if (getDecl()->isBitField())
-    return UnknownVal();
-
-  DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
-
-  // A zero-length array at the end of a struct often stands for dynamically-
-  // allocated extra memory.
-  if (Extent.isZeroConstant()) {
-    QualType T = getDesugaredValueType(svalBuilder.getContext());
-
-    if (isa<ConstantArrayType>(T))
-      return UnknownVal();
-  }
-
-  return Extent;
-}
-
-DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
-  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
-}
-
-DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
-  return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
-}
-
-DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
-  return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
-                                svalBuilder.getArrayIndexType());
-}
-
 ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
     : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
 
@@ -717,11 +667,78 @@
 // MemRegionManager methods.
 //===----------------------------------------------------------------------===//
 
+static DefinedOrUnknownSVal getTypeSize(QualType Ty, ASTContext &Ctx,
+                                          SValBuilder &SVB) {
+  CharUnits Size = Ctx.getTypeSizeInChars(Ty);
+  QualType SizeTy = SVB.getArrayIndexType();
+  return SVB.makeIntVal(Size.getQuantity(), SizeTy);
+}
+
+DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
+                                                     SValBuilder &SVB) const {
+  const auto *SR = cast<SubRegion>(MR);
+  SymbolManager &SymMgr = SVB.getSymbolManager();
+
+  switch (SR->getKind()) {
+  case MemRegion::AllocaRegionKind:
+  case MemRegion::SymbolicRegionKind:
+    return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
+  case MemRegion::StringRegionKind:
+    return SVB.makeIntVal(
+        cast<StringRegion>(SR)->getStringLiteral()->getByteLength() + 1,
+        SVB.getArrayIndexType());
+  case MemRegion::CompoundLiteralRegionKind:
+  case MemRegion::CXXBaseObjectRegionKind:
+  case MemRegion::CXXDerivedObjectRegionKind:
+  case MemRegion::CXXTempObjectRegionKind:
+  case MemRegion::CXXThisRegionKind:
+  case MemRegion::ObjCIvarRegionKind:
+  case MemRegion::VarRegionKind:
+  case MemRegion::ElementRegionKind:
+  case MemRegion::ObjCStringRegionKind: {
+    QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
+    if (isa<VariableArrayType>(Ty))
+      return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
+
+    if (Ty->isIncompleteType())
+      return UnknownVal();
+
+    return getTypeSize(Ty, Ctx, SVB);
+  }
+  case MemRegion::FieldRegionKind: {
+    // Force callers to deal with bitfields explicitly.
+    if (cast<FieldRegion>(SR)->getDecl()->isBitField())
+      return UnknownVal();
+
+    QualType Ty = cast<TypedValueRegion>(SR)->getDesugaredValueType(Ctx);
+    DefinedOrUnknownSVal Size = getTypeSize(Ty, Ctx, SVB);
+
+    // A zero-length array at the end of a struct often stands for dynamically
+    // allocated extra memory.
+    if (Size.isZeroConstant()) {
+      if (isa<ConstantArrayType>(Ty))
+        return UnknownVal();
+    }
+
+    return Size;
+  }
+    // FIXME: The following are being used in 'SimpleSValBuilder' and in
+    // 'ArrayBoundChecker::checkLocation' because there is no symbol to
+    // represent the regions more appropriately.
+  case MemRegion::BlockDataRegionKind:
+  case MemRegion::BlockCodeRegionKind:
+  case MemRegion::FunctionCodeRegionKind:
+    return nonloc::SymbolVal(SymMgr.getExtentSymbol(SR));
+  default:
+    llvm_unreachable("Unhandled region");
+  }
+}
+
 template <typename REG>
 const REG *MemRegionManager::LazyAllocate(REG*& region) {
   if (!region) {
     region = A.Allocate<REG>();
-    new (region) REG(this);
+    new (region) REG(*this);
   }
 
   return region;
@@ -746,7 +763,7 @@
     return R;
 
   R = A.Allocate<StackLocalsSpaceRegion>();
-  new (R) StackLocalsSpaceRegion(this, STC);
+  new (R) StackLocalsSpaceRegion(*this, STC);
   return R;
 }
 
@@ -759,7 +776,7 @@
     return R;
 
   R = A.Allocate<StackArgumentsSpaceRegion>();
-  new (R) StackArgumentsSpaceRegion(this, STC);
+  new (R) StackArgumentsSpaceRegion(*this, STC);
   return R;
 }
 
@@ -781,7 +798,7 @@
     return R;
 
   R = A.Allocate<StaticGlobalSpaceRegion>();
-  new (R) StaticGlobalSpaceRegion(this, CR);
+  new (R) StaticGlobalSpaceRegion(*this, CR);
   return R;
 }
 
@@ -850,7 +867,7 @@
   if (D->hasGlobalStorage() && !D->isStaticLocal()) {
 
     // First handle the globals defined in system headers.
-    if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
+    if (Ctx.getSourceManager().isInSystemHeader(D->getLocation())) {
       // Whitelist the system globals which often DO GET modified, assume the
       // rest are immutable.
       if (D->getName().find("errno") != StringRef::npos)
@@ -914,7 +931,7 @@
           T = getContext().getBlockPointerType(T);
 
           const BlockCodeRegion *BTR =
-            getBlockCodeRegion(BD, C.getCanonicalType(T),
+            getBlockCodeRegion(BD, Ctx.getCanonicalType(T),
                                STC->getAnalysisDeclContext());
           sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
                                   BTR);
@@ -1476,7 +1493,7 @@
 
 std::pair<const VarRegion *, const VarRegion *>
 BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
-  MemRegionManager &MemMgr = *getMemRegionManager();
+  MemRegionManager &MemMgr = getMemRegionManager();
   const VarRegion *VR = nullptr;
   const VarRegion *OriginalVR = nullptr;
 
@@ -1511,7 +1528,7 @@
     return;
   }
 
-  MemRegionManager &MemMgr = *getMemRegionManager();
+  MemRegionManager &MemMgr = getMemRegionManager();
   llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
   BumpVectorContext BC(A);
 
Index: clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
===================================================================
--- /dev/null
+++ clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
@@ -0,0 +1,30 @@
+//===- DynamicSize.cpp - Dynamic size related APIs --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines APIs that track and query dynamic size information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+
+namespace clang {
+namespace ento {
+
+DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
+                                    SValBuilder &SVB) {
+  return MR->getMemRegionManager().getStaticSize(MR, SVB);
+}
+
+} // namespace ento
+} // namespace clang
Index: clang/lib/StaticAnalyzer/Core/CMakeLists.txt
===================================================================
--- clang/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ clang/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -16,6 +16,7 @@
   CommonBugCategories.cpp
   ConstraintManager.cpp
   CoreEngine.cpp
+  DynamicSize.cpp
   DynamicType.cpp
   Environment.cpp
   ExplodedGraph.cpp
Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -358,7 +358,7 @@
 
 public:
   NoStoreFuncVisitor(const SubRegion *R, bugreporter::TrackingKind TKind)
-      : RegionOfInterest(R), MmrMgr(*R->getMemRegionManager()),
+      : RegionOfInterest(R), MmrMgr(R->getMemRegionManager()),
         SM(MmrMgr.getContext().getSourceManager()),
         PP(MmrMgr.getContext().getPrintingPolicy()), TKind(TKind) {}
 
Index: clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -14,12 +14,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "Taint.h"
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
@@ -165,13 +166,14 @@
   SVal ArraySizeVal = svalBuilder.evalBinOpNN(
       state, BO_Mul, ArrayLength, EleSizeVal.castAs<NonLoc>(), SizeTy);
 
-  // Finally, assume that the array's extent matches the given size.
+  // Finally, assume that the array's size matches the given size.
   const LocationContext *LC = C.getLocationContext();
-  DefinedOrUnknownSVal Extent =
-    state->getRegion(VD, LC)->getExtent(svalBuilder);
+  DefinedOrUnknownSVal DynSize =
+      getDynamicSize(state, state->getRegion(VD, LC), svalBuilder);
+
   DefinedOrUnknownSVal ArraySize = ArraySizeVal.castAs<DefinedOrUnknownSVal>();
   DefinedOrUnknownSVal sizeIsKnown =
-    svalBuilder.evalEQ(state, Extent, ArraySize);
+      svalBuilder.evalEQ(state, DynSize, ArraySize);
   state = state->assume(sizeIsKnown, true);
 
   // Assume should not fail at this point.
Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -57,6 +57,7 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
@@ -1402,15 +1403,16 @@
   CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType);
 
   if (ElementCount.getAs<NonLoc>()) {
-    DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder);
+    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 extentMatchesSize = svalBuilder.evalEQ(
-        State, Extent, SizeInBytes.castAs<DefinedOrUnknownSVal>());
-    State = State->assume(extentMatchesSize, true);
+    DefinedOrUnknownSVal DynSizeMatchesSize = svalBuilder.evalEQ(
+        State, DynSize, SizeInBytes.castAs<DefinedOrUnknownSVal>());
+    State = State->assume(DynSizeMatchesSize, true);
   }
   return State;
 }
@@ -1542,12 +1544,12 @@
     return nullptr;
   if (Optional<DefinedOrUnknownSVal> DefinedSize =
           Size.getAs<DefinedOrUnknownSVal>()) {
-    SValBuilder &svalBuilder = C.getSValBuilder();
-    DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
-    DefinedOrUnknownSVal extentMatchesSize =
-        svalBuilder.evalEQ(State, Extent, *DefinedSize);
+    DefinedOrUnknownSVal DynSize = getDynamicSize(State, R, svalBuilder);
+
+    DefinedOrUnknownSVal DynSizeMatchesSize =
+        svalBuilder.evalEQ(State, DynSize, *DefinedSize);
 
-    State = State->assume(extentMatchesSize, true);
+    State = State->assume(DynSizeMatchesSize, true);
     assert(State);
   }
 
Index: clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
@@ -146,7 +146,7 @@
     llvm::SmallVector<const MemRegion *, 2> &ReqRegions,
     const MemRegion *const MR, const CallEvent &CE, CheckerContext &Ctx) const {
 
-  MemRegionManager *const RegionManager = MR->getMemRegionManager();
+  MemRegionManager &RegionManager = MR->getMemRegionManager();
 
   if (FuncClassifier->isMPI_Waitall(CE.getCalleeIdentifier())) {
     const SubRegion *SuperRegion{nullptr};
@@ -168,7 +168,7 @@
     for (size_t i = 0; i < ArrSize; ++i) {
       const NonLoc Idx = Ctx.getSValBuilder().makeArrayIndex(i);
 
-      const ElementRegion *const ER = RegionManager->getElementRegion(
+      const ElementRegion *const ER = RegionManager.getElementRegion(
           CE.getArgExpr(1)->getType()->getPointeeType(), Idx, SuperRegion,
           Ctx.getASTContext());
 
Index: clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -13,6 +13,7 @@
 #include "clang/StaticAnalyzer/Core/IssueHash.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ScopedPrinter.h"
 
@@ -234,8 +235,9 @@
   }
 
   ProgramStateRef State = C.getState();
-  State = State->BindExpr(CE, C.getLocationContext(),
-                          MR->getExtent(C.getSValBuilder()));
+  DefinedOrUnknownSVal Size = getDynamicSize(State, MR, C.getSValBuilder());
+
+  State = State->BindExpr(CE, C.getLocationContext(), Size);
   C.addTransition(State);
 }
 
Index: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
@@ -1,6 +1,7 @@
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "llvm/Support/FormatVariadic.h"
 
 using namespace clang;
@@ -42,7 +43,7 @@
   NonLoc OffsetInBytes = SvalBuilder.makeArrayIndex(
       Offset.getOffset() / C.getASTContext().getCharWidth());
   DefinedOrUnknownSVal ExtentInBytes =
-      BaseRegion->castAs<SubRegion>()->getExtent(SvalBuilder);
+      getDynamicSize(State, BaseRegion, SvalBuilder);
 
   return SvalBuilder.evalBinOp(State, BinaryOperator::Opcode::BO_Sub,
                                ExtentInBytes, OffsetInBytes,
Index: clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
@@ -10,12 +10,14 @@
 // whether the size of the symbolic region is a multiple of the size of T.
 //
 //===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+
 #include "clang/AST/CharUnits.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 
 using namespace clang;
 using namespace ento;
@@ -109,12 +111,13 @@
     return;
 
   SValBuilder &svalBuilder = C.getSValBuilder();
-  SVal extent = SR->getExtent(svalBuilder);
-  const llvm::APSInt *extentInt = svalBuilder.getKnownValue(state, extent);
-  if (!extentInt)
+
+  DefinedOrUnknownSVal Size = getDynamicSize(state, SR, svalBuilder);
+  const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
+  if (!SizeInt)
     return;
 
-  CharUnits regionSize = CharUnits::fromQuantity(extentInt->getSExtValue());
+  CharUnits regionSize = CharUnits::fromQuantity(SizeInt->getZExtValue());
   CharUnits typeSize = C.getASTContext().getTypeSizeInChars(ToPointeeTy);
 
   // Ignore void, and a few other un-sizeable types.
Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -11,14 +11,15 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "InterCheckerAPI.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
@@ -327,10 +328,8 @@
 
   // Get the size of the array.
   const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
-  SValBuilder &svalBuilder = C.getSValBuilder();
-  SVal Extent =
-    svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
-  DefinedOrUnknownSVal Size = Extent.castAs<DefinedOrUnknownSVal>();
+  DefinedOrUnknownSVal Size =
+      getDynamicSize(state, superReg, C.getSValBuilder());
 
   // Get the index of the accessed element.
   DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
@@ -935,14 +934,12 @@
 
   // Get the size of the array.
   const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
-  SVal Extent =
-      svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
-  DefinedOrUnknownSVal ExtentSize = Extent.castAs<DefinedOrUnknownSVal>();
+  DefinedOrUnknownSVal SizeDV = getDynamicSize(state, superReg, svalBuilder);
 
   // Get the index of the accessed element.
   DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
 
-  ProgramStateRef StInBound = state->assumeInBound(Idx, ExtentSize, true);
+  ProgramStateRef StInBound = state->assumeInBound(Idx, SizeDV, true);
 
   return static_cast<bool>(StInBound);
 }
@@ -1069,13 +1066,12 @@
   // 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 extent.
-    auto *SubReg = cast<SubRegion>(BR);
-    DefinedOrUnknownSVal Extent = SubReg->getExtent(svalBuilder);
+    // Get the base region's size.
+    DefinedOrUnknownSVal SizeDV = getDynamicSize(State, BR, svalBuilder);
 
     ProgramStateRef StateWholeReg, StateNotWholeReg;
     std::tie(StateWholeReg, StateNotWholeReg) =
-        State->assume(svalBuilder.evalEQ(State, Extent, *SizeNL));
+        State->assume(svalBuilder.evalEQ(State, SizeDV, *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
@@ -10,12 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/Basic/Builtins.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 
 using namespace clang;
 using namespace ento;
@@ -90,10 +91,10 @@
       return true; // Return true to model purity.
 
     SValBuilder& svalBuilder = C.getSValBuilder();
-    DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
-    DefinedOrUnknownSVal extentMatchesSizeArg =
-      svalBuilder.evalEQ(state, Extent, Size.castAs<DefinedOrUnknownSVal>());
-    state = state->assume(extentMatchesSizeArg, true);
+    DefinedOrUnknownSVal DynSize = getDynamicSize(state, R, svalBuilder);
+    DefinedOrUnknownSVal DynSizeMatchesSizeArg =
+        svalBuilder.evalEQ(state, DynSize, Size.castAs<DefinedOrUnknownSVal>());
+    state = state->assume(DynSizeMatchesSizeArg, true);
     assert(state && "The region should not have any previous constraints");
 
     C.addTransition(state->BindExpr(CE, LCtx, loc::MemRegionVal(R)));
Index: clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -12,13 +12,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "Taint.h"
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
@@ -175,24 +176,23 @@
   }
 
   do {
-    // CHECK UPPER BOUND: Is byteOffset >= extent(baseRegion)?  If so,
+    // CHECK UPPER BOUND: Is byteOffset >= size(baseRegion)?  If so,
     // we are doing a load/store after the last valid offset.
-    DefinedOrUnknownSVal extentVal =
-      rawOffset.getRegion()->getExtent(svalBuilder);
-    if (!extentVal.getAs<NonLoc>())
+    const MemRegion *MR = rawOffset.getRegion();
+    DefinedOrUnknownSVal Size = getDynamicSize(state, MR, svalBuilder);
+    if (!Size.getAs<NonLoc>())
       break;
 
-    if (extentVal.getAs<nonloc::ConcreteInt>()) {
+    if (Size.getAs<nonloc::ConcreteInt>()) {
       std::pair<NonLoc, nonloc::ConcreteInt> simplifiedOffsets =
           getSimplifiedOffsets(rawOffset.getByteOffset(),
-                               extentVal.castAs<nonloc::ConcreteInt>(),
-                               svalBuilder);
+                               Size.castAs<nonloc::ConcreteInt>(), svalBuilder);
       rawOffsetVal = simplifiedOffsets.first;
-      extentVal = simplifiedOffsets.second;
+      Size = simplifiedOffsets.second;
     }
 
     SVal upperbound = svalBuilder.evalBinOpNN(state, BO_GE, rawOffsetVal,
-                                              extentVal.castAs<NonLoc>(),
+                                              Size.castAs<NonLoc>(),
                                               svalBuilder.getConditionType());
 
     Optional<NonLoc> upperboundToCheck = upperbound.getAs<NonLoc>();
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -112,7 +112,7 @@
 
   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
 
-  virtual MemRegionManager* getMemRegionManager() const = 0;
+  virtual MemRegionManager &getMemRegionManager() const = 0;
 
   const MemSpaceRegion *getMemorySpace() const;
 
@@ -198,14 +198,13 @@
 ///  for example, the set of global variables, the stack frame, etc.
 class MemSpaceRegion : public MemRegion {
 protected:
-  MemRegionManager *Mgr;
+  MemRegionManager &Mgr;
 
-  MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) {
+  MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) {
     assert(classof(this));
-    assert(mgr);
   }
 
-  MemRegionManager* getMemRegionManager() const override { return Mgr; }
+  MemRegionManager &getMemRegionManager() const override { return Mgr; }
 
 public:
   bool isBoundable() const override { return false; }
@@ -223,7 +222,7 @@
 class CodeSpaceRegion : public MemSpaceRegion {
   friend class MemRegionManager;
 
-  CodeSpaceRegion(MemRegionManager *mgr)
+  CodeSpaceRegion(MemRegionManager &mgr)
       : MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
 
 public:
@@ -238,7 +237,7 @@
   virtual void anchor();
 
 protected:
-  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) {
+  GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) {
     assert(classof(this));
   }
 
@@ -259,7 +258,7 @@
 
   const CodeTextRegion *CR;
 
-  StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
+  StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr)
       : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
     assert(cr);
   }
@@ -286,7 +285,7 @@
   void anchor() override;
 
 protected:
-  NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
+  NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
       : GlobalsSpaceRegion(mgr, k) {
     assert(classof(this));
   }
@@ -304,7 +303,7 @@
 class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
   friend class MemRegionManager;
 
-  GlobalSystemSpaceRegion(MemRegionManager *mgr)
+  GlobalSystemSpaceRegion(MemRegionManager &mgr)
       : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
 
 public:
@@ -323,7 +322,7 @@
 class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
   friend class MemRegionManager;
 
-  GlobalImmutableSpaceRegion(MemRegionManager *mgr)
+  GlobalImmutableSpaceRegion(MemRegionManager &mgr)
       : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
 
 public:
@@ -340,7 +339,7 @@
 class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
   friend class MemRegionManager;
 
-  GlobalInternalSpaceRegion(MemRegionManager *mgr)
+  GlobalInternalSpaceRegion(MemRegionManager &mgr)
       : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
 
 public:
@@ -354,7 +353,7 @@
 class HeapSpaceRegion : public MemSpaceRegion {
   friend class MemRegionManager;
 
-  HeapSpaceRegion(MemRegionManager *mgr)
+  HeapSpaceRegion(MemRegionManager &mgr)
       : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
 
 public:
@@ -368,7 +367,7 @@
 class UnknownSpaceRegion : public MemSpaceRegion {
   friend class MemRegionManager;
 
-  UnknownSpaceRegion(MemRegionManager *mgr)
+  UnknownSpaceRegion(MemRegionManager &mgr)
       : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
 
 public:
@@ -385,7 +384,7 @@
   const StackFrameContext *SFC;
 
 protected:
-  StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
+  StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc)
       : MemSpaceRegion(mgr, k), SFC(sfc) {
     assert(classof(this));
     assert(sfc);
@@ -405,7 +404,7 @@
 class StackLocalsSpaceRegion : public StackSpaceRegion {
   friend class MemRegionManager;
 
-  StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+  StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
       : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
 
 public:
@@ -420,7 +419,7 @@
 private:
   friend class MemRegionManager;
 
-  StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+  StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc)
       : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
 
 public:
@@ -449,12 +448,7 @@
     return superRegion;
   }
 
-  /// getExtent - Returns the size of the region in bytes.
-  virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const {
-    return UnknownVal();
-  }
-
-  MemRegionManager* getMemRegionManager() const override;
+  MemRegionManager &getMemRegionManager() const override;
 
   bool isSubRegionOf(const MemRegion* R) const override;
 
@@ -491,8 +485,6 @@
 
   bool isBoundable() const override { return true; }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
   void dumpToStream(raw_ostream &os) const override;
@@ -552,8 +544,6 @@
     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
   }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
     return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
@@ -782,8 +772,6 @@
 
   bool isBoundable() const override { return true; }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -817,8 +805,6 @@
 
   QualType getValueType() const override { return Str->getType(); }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
   bool isBoundable() const override { return false; }
 
   void Profile(llvm::FoldingSetNodeID& ID) const override {
@@ -1021,8 +1007,6 @@
     return getDecl()->getType();
   }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
-
   void dumpToStream(raw_ostream &os) const override;
 
   bool canPrintPretty() const override;
@@ -1242,8 +1226,9 @@
 //===----------------------------------------------------------------------===//
 
 class MemRegionManager {
-  ASTContext &C;
+  ASTContext &Ctx;
   llvm::BumpPtrAllocator& A;
+
   llvm::FoldingSet<MemRegion> Regions;
 
   GlobalInternalSpaceRegion *InternalGlobals = nullptr;
@@ -1262,13 +1247,18 @@
   CodeSpaceRegion *code = nullptr;
 
 public:
-  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {}
+  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {}
   ~MemRegionManager();
 
-  ASTContext &getContext() { return C; }
+  ASTContext &getContext() { return Ctx; }
 
   llvm::BumpPtrAllocator &getAllocator() { return A; }
 
+  /// \returns The static size in bytes of the region \p MR.
+  /// \note The region \p MR must be a 'SubRegion'.
+  DefinedOrUnknownSVal getStaticSize(const MemRegion *MR,
+                                     SValBuilder &SVB) const;
+
   /// getStackLocalsRegion - Retrieve the memory region associated with the
   ///  specified stack frame.
   const StackLocalsSpaceRegion *
@@ -1434,7 +1424,7 @@
 //===----------------------------------------------------------------------===//
 
 inline ASTContext &MemRegion::getContext() const {
-  return getMemRegionManager()->getContext();
+  return getMemRegionManager().getContext();
 }
 
 //===----------------------------------------------------------------------===//
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
===================================================================
--- /dev/null
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
@@ -0,0 +1,32 @@
+//===- DynamicSize.h - Dynamic size related APIs ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines APIs that track and query dynamic size information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICSIZE_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICSIZE_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
+
+namespace clang {
+namespace ento {
+
+/// Get the stored dynamic size for the region \p MR.
+DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
+                                    SValBuilder &SVB);
+
+} // namespace ento
+} // namespace clang
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICSIZE_H
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to