Charusso updated this revision to Diff 227524.
Charusso marked 2 inline comments as done.
Charusso added a comment.
- Fix.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D69599/new/
https://reviews.llvm.org/D69599
Files:
clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
clang/lib/StaticAnalyzer/Core/RegionStore.cpp
Index: clang/lib/StaticAnalyzer/Core/RegionStore.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -622,15 +622,6 @@
StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
SymbolReaper& SymReaper) override;
- //===------------------------------------------------------------------===//
- // Region "extents".
- //===------------------------------------------------------------------===//
-
- // FIXME: This method will soon be eliminated; see the note in Store.h.
- DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state,
- const MemRegion* R,
- QualType EleTy) override;
-
//===------------------------------------------------------------------===//
// Utility methods.
//===------------------------------------------------------------------===//
@@ -1387,37 +1378,6 @@
return StoreRef(B.asStore(), *this);
}
-//===----------------------------------------------------------------------===//
-// Extents for regions.
-//===----------------------------------------------------------------------===//
-
-DefinedOrUnknownSVal
-RegionStoreManager::getSizeInElements(ProgramStateRef state,
- const MemRegion *R,
- QualType EleTy) {
- DefinedOrUnknownSVal Size = getDynamicSize(state, R, svalBuilder);
- const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
- if (!SizeInt)
- return UnknownVal();
-
- CharUnits RegionSize = CharUnits::fromQuantity(SizeInt->getSExtValue());
-
- if (Ctx.getAsVariableArrayType(EleTy)) {
- // FIXME: We need to track extra state to properly record the size
- // of VLAs. Returning UnknownVal here, however, is a stop-gap so that
- // we don't have a divide-by-zero below.
- return UnknownVal();
- }
-
- CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
-
- // If a variable is reinterpreted as a type that doesn't fit into a larger
- // type evenly, round it down.
- // This is a signed value, since it's used in arithmetic with signed indices.
- return svalBuilder.makeIntVal(RegionSize / EleSize,
- svalBuilder.getArrayIndexType());
-}
-
//===----------------------------------------------------------------------===//
// Location and region casting.
//===----------------------------------------------------------------------===//
Index: clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
+++ clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
+#include "clang/AST/Expr.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
@@ -26,5 +27,37 @@
return MR->getMemRegionManager().getStaticSize(MR, SVB);
}
+DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
+ const MemRegion *MR,
+ SValBuilder &SVB,
+ QualType ElementTy) {
+ MemRegionManager &MemMgr = MR->getMemRegionManager();
+ ASTContext &Ctx = MemMgr.getContext();
+
+ CharUnits ElementSize = Ctx.getTypeSizeInChars(ElementTy);
+ DefinedOrUnknownSVal Size = getDynamicSize(State, MR, SVB);
+
+ if (const llvm::APSInt *SizeInt = SVB.getKnownValue(State, Size)) {
+ CharUnits RegionSize = CharUnits::fromQuantity(SizeInt->getSExtValue());
+
+ // If a variable is reinterpreted as a type that doesn't fit into a larger
+ // type evenly, round it down.
+ // This is a signed value, since it's used in arithmetic with signed
+ // indices.
+ return SVB.makeIntVal(RegionSize / ElementSize, SVB.getArrayIndexType());
+ }
+
+ // Try to rely on the 'SValBuilder'.
+ SVal ElementSizeV = SVB.makeIntVal(
+ llvm::APSInt(Ctx.getTypeSizeInChars(ElementTy).getQuantity()));
+ SVal DivisionV =
+ SVB.evalBinOp(State, BO_Div, Size, ElementSizeV, SVB.getArrayIndexType());
+
+ if (auto DV = DivisionV.getAs<DefinedOrUnknownSVal>())
+ return *DV;
+
+ return UnknownVal();
+}
+
} // namespace ento
} // namespace clang
Index: clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -16,6 +16,7 @@
#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 "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
@@ -50,10 +51,10 @@
return false;
DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
- DefinedOrUnknownSVal NumElements = C.getStoreManager().getSizeInElements(
- state, ER->getSuperRegion(), ER->getValueType());
- ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
- ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
+ DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
+ state, ER->getSuperRegion(), C.getSValBuilder(), ER->getValueType());
+ ProgramStateRef StInBound = state->assumeInBound(Idx, ElementCount, true);
+ ProgramStateRef StOutBound = state->assumeInBound(Idx, ElementCount, false);
return StOutBound && !StInBound;
}
Index: clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -16,6 +16,7 @@
#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 "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
using namespace clang;
@@ -51,15 +52,14 @@
// pointer casts.
if (Idx.isZeroConstant())
return;
+
// FIXME: All of this out-of-bounds checking should eventually be refactored
// into a common place.
+ DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
+ state, ER->getSuperRegion(), C.getSValBuilder(), ER->getValueType());
- DefinedOrUnknownSVal NumElements
- = C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
- ER->getValueType());
-
- ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
- ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
+ ProgramStateRef StInBound = state->assumeInBound(Idx, ElementCount, true);
+ ProgramStateRef StOutBound = state->assumeInBound(Idx, ElementCount, false);
if (StOutBound && !StInBound) {
ExplodedNode *N = C.generateErrorNode(StOutBound);
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
@@ -16,6 +16,7 @@
#include "MPIChecker.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
namespace clang {
namespace ento {
@@ -160,10 +161,11 @@
return;
}
- const auto &Size = Ctx.getStoreManager().getSizeInElements(
- Ctx.getState(), SuperRegion,
+ DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
+ Ctx.getState(), SuperRegion, Ctx.getSValBuilder(),
CE.getArgExpr(1)->getType()->getPointeeType());
- const llvm::APSInt &ArrSize = Size.getAs<nonloc::ConcreteInt>()->getValue();
+ const llvm::APSInt &ArrSize =
+ ElementCount.getAs<nonloc::ConcreteInt>()->getValue();
for (size_t i = 0; i < ArrSize; ++i) {
const NonLoc Idx = Ctx.getSValBuilder().makeArrayIndex(i);
Index: clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -16,6 +16,7 @@
#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 "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
using namespace clang;
@@ -54,12 +55,11 @@
ProgramStateRef state = C.getState();
// Get the size of the array.
- DefinedOrUnknownSVal NumElements
- = C.getStoreManager().getSizeInElements(state, ER->getSuperRegion(),
- ER->getValueType());
+ DefinedOrUnknownSVal ElementCount = getDynamicElementCount(
+ state, ER->getSuperRegion(), C.getSValBuilder(), ER->getValueType());
- ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
- ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
+ ProgramStateRef StInBound = state->assumeInBound(Idx, ElementCount, true);
+ ProgramStateRef StOutBound = state->assumeInBound(Idx, ElementCount, false);
if (StOutBound && !StInBound) {
ExplodedNode *N = C.generateErrorNode(StOutBound);
if (!N)
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -148,14 +148,6 @@
virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base);
- // FIXME: This should soon be eliminated altogether; clients should deal with
- // region extents directly.
- virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state,
- const MemRegion *region,
- QualType EleTy) {
- return UnknownVal();
- }
-
/// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
/// conversions between arrays and pointers.
virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0;
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
@@ -26,6 +26,12 @@
DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
SValBuilder &SVB);
+/// Get the stored element count of the region \p MR.
+DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
+ const MemRegion *MR,
+ SValBuilder &SVB,
+ QualType ElementTy);
+
} // namespace ento
} // namespace clang
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits