forked from OSchip/llvm-project
[analyzer] DynamicSize: Remove 'getSizeInElements()' from store
Summary: This patch uses the new `DynamicSize.cpp` to serve dynamic information. Previously it was static and probably imprecise data. Reviewed By: NoQ Differential Revision: https://reviews.llvm.org/D69599
This commit is contained in:
parent
4801522432
commit
af3d0d1628
|
@ -26,6 +26,12 @@ namespace ento {
|
|||
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
|
||||
|
||||
|
|
|
@ -148,14 +148,6 @@ public:
|
|||
|
||||
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;
|
||||
|
|
|
@ -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 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
|
|||
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)
|
||||
|
|
|
@ -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 @@ void MPIChecker::allRegionsUsedByWait(
|
|||
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);
|
||||
|
|
|
@ -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 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
|
|||
// 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);
|
||||
|
||||
|
|
|
@ -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 @@ static bool isArrayIndexOutOfBounds(CheckerContext &C, const Expr *Ex) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,22 @@ DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR,
|
|||
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();
|
||||
|
||||
DefinedOrUnknownSVal Size = getDynamicSize(State, MR, SVB);
|
||||
SVal ElementSizeV = SVB.makeIntVal(
|
||||
Ctx.getTypeSizeInChars(ElementTy).getQuantity(), SVB.getArrayIndexType());
|
||||
|
||||
SVal DivisionV =
|
||||
SVB.evalBinOp(State, BO_Div, Size, ElementSizeV, SVB.getArrayIndexType());
|
||||
|
||||
return DivisionV.castAs<DefinedOrUnknownSVal>();
|
||||
}
|
||||
|
||||
} // namespace ento
|
||||
} // namespace clang
|
||||
|
|
|
@ -622,15 +622,6 @@ public: // Part of public interface to class.
|
|||
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 @@ RegionStoreManager::invalidateRegions(Store store,
|
|||
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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue