forked from OSchip/llvm-project
[analyzer] DynamicSize: Remove 'getExtent()' from regions
Summary: This patch introduces a placeholder for representing the dynamic size of regions. It also moves the `getExtent()` method of `SubRegions` to the `MemRegionManager` as `getStaticSize()`. Reviewed By: NoQ Differential Revision: https://reviews.llvm.org/D69540
This commit is contained in:
parent
523896f64a
commit
601687bf73
|
@ -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
|
|
@ -112,7 +112,7 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
/// 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 @@ public:
|
|||
class CodeSpaceRegion : public MemSpaceRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
CodeSpaceRegion(MemRegionManager *mgr)
|
||||
CodeSpaceRegion(MemRegionManager &mgr)
|
||||
: MemSpaceRegion(mgr, CodeSpaceRegionKind) {}
|
||||
|
||||
public:
|
||||
|
@ -238,7 +237,7 @@ class GlobalsSpaceRegion : public MemSpaceRegion {
|
|||
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 @@ class StaticGlobalSpaceRegion : public GlobalsSpaceRegion {
|
|||
|
||||
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 @@ class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
|
|||
void anchor() override;
|
||||
|
||||
protected:
|
||||
NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
|
||||
NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k)
|
||||
: GlobalsSpaceRegion(mgr, k) {
|
||||
assert(classof(this));
|
||||
}
|
||||
|
@ -304,7 +303,7 @@ public:
|
|||
class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
GlobalSystemSpaceRegion(MemRegionManager *mgr)
|
||||
GlobalSystemSpaceRegion(MemRegionManager &mgr)
|
||||
: NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {}
|
||||
|
||||
public:
|
||||
|
@ -323,7 +322,7 @@ public:
|
|||
class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
GlobalImmutableSpaceRegion(MemRegionManager *mgr)
|
||||
GlobalImmutableSpaceRegion(MemRegionManager &mgr)
|
||||
: NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {}
|
||||
|
||||
public:
|
||||
|
@ -340,7 +339,7 @@ public:
|
|||
class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
GlobalInternalSpaceRegion(MemRegionManager *mgr)
|
||||
GlobalInternalSpaceRegion(MemRegionManager &mgr)
|
||||
: NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {}
|
||||
|
||||
public:
|
||||
|
@ -354,7 +353,7 @@ public:
|
|||
class HeapSpaceRegion : public MemSpaceRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
HeapSpaceRegion(MemRegionManager *mgr)
|
||||
HeapSpaceRegion(MemRegionManager &mgr)
|
||||
: MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
|
||||
|
||||
public:
|
||||
|
@ -368,7 +367,7 @@ public:
|
|||
class UnknownSpaceRegion : public MemSpaceRegion {
|
||||
friend class MemRegionManager;
|
||||
|
||||
UnknownSpaceRegion(MemRegionManager *mgr)
|
||||
UnknownSpaceRegion(MemRegionManager &mgr)
|
||||
: MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
|
||||
|
||||
public:
|
||||
|
@ -385,7 +384,7 @@ class StackSpaceRegion : public MemSpaceRegion {
|
|||
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 @@ public:
|
|||
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 @@ class StackArgumentsSpaceRegion : public StackSpaceRegion {
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
return getDecl()->getType();
|
||||
}
|
||||
|
||||
DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
|
||||
|
||||
void dumpToStream(raw_ostream &os) const override;
|
||||
|
||||
bool canPrintPretty() const override;
|
||||
|
@ -1242,8 +1226,9 @@ const RegionTy* MemRegion::castAs() const {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class MemRegionManager {
|
||||
ASTContext &C;
|
||||
ASTContext &Ctx;
|
||||
llvm::BumpPtrAllocator& A;
|
||||
|
||||
llvm::FoldingSet<MemRegion> Regions;
|
||||
|
||||
GlobalInternalSpaceRegion *InternalGlobals = nullptr;
|
||||
|
@ -1262,13 +1247,18 @@ class MemRegionManager {
|
|||
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 @@ private:
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
inline ASTContext &MemRegion::getContext() const {
|
||||
return getMemRegionManager()->getContext();
|
||||
return getMemRegionManager().getContext();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
|
|||
}
|
||||
|
||||
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>();
|
||||
|
|
|
@ -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 @@ bool BuiltinFunctionChecker::evalCall(const CallEvent &Call,
|
|||
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)));
|
||||
|
|
|
@ -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 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
|
|||
|
||||
// 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 @@ bool CStringChecker::IsFirstBufInBound(CheckerContext &C,
|
|||
|
||||
// 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 @@ bool CStringChecker::memsetAux(const Expr *DstBuffer, SVal CharVal,
|
|||
// 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.
|
||||
|
|
|
@ -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 @@ void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
|
|||
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.
|
||||
|
|
|
@ -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 @@ SVal PlacementNewChecker::getExtentSizeOfPlace(const Expr *Place,
|
|||
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,
|
||||
|
|
|
@ -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 @@ void ExprInspectionChecker::analyzerGetExtent(const CallExpr *CE,
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ void MPIChecker::allRegionsUsedByWait(
|
|||
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 @@ void MPIChecker::allRegionsUsedByWait(
|
|||
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());
|
||||
|
||||
|
|
|
@ -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 @@ ProgramStateRef MallocChecker::addExtentSize(CheckerContext &C,
|
|||
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 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
|
|||
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);
|
||||
|
||||
State = State->assume(extentMatchesSize, true);
|
||||
DefinedOrUnknownSVal DynSizeMatchesSize =
|
||||
svalBuilder.evalEQ(State, DynSize, *DefinedSize);
|
||||
|
||||
State = State->assume(DynSizeMatchesSize, true);
|
||||
assert(State);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
|
|||
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.
|
||||
|
|
|
@ -358,7 +358,7 @@ class NoStoreFuncVisitor final : public BugReporterVisitor {
|
|||
|
||||
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) {}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ add_clang_library(clangStaticAnalyzerCore
|
|||
CommonBugCategories.cpp
|
||||
ConstraintManager.cpp
|
||||
CoreEngine.cpp
|
||||
DynamicSize.cpp
|
||||
DynamicType.cpp
|
||||
Environment.cpp
|
||||
ExplodedGraph.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
|
|
@ -142,7 +142,7 @@ bool SubRegion::isSubRegionOf(const MemRegion* R) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
MemRegionManager* SubRegion::getMemRegionManager() const {
|
||||
MemRegionManager &SubRegion::getMemRegionManager() const {
|
||||
const SubRegion* r = this;
|
||||
do {
|
||||
const MemRegion *superRegion = r->getSuperRegion();
|
||||
|
@ -159,56 +159,6 @@ const StackFrameContext *VarRegion::getStackFrame() const {
|
|||
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 @@ SourceRange MemRegion::sourceRange() const {
|
|||
// 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 @@ MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
|
|||
return R;
|
||||
|
||||
R = A.Allocate<StackLocalsSpaceRegion>();
|
||||
new (R) StackLocalsSpaceRegion(this, STC);
|
||||
new (R) StackLocalsSpaceRegion(*this, STC);
|
||||
return R;
|
||||
}
|
||||
|
||||
|
@ -759,7 +776,7 @@ MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
|
|||
return R;
|
||||
|
||||
R = A.Allocate<StackArgumentsSpaceRegion>();
|
||||
new (R) StackArgumentsSpaceRegion(this, STC);
|
||||
new (R) StackArgumentsSpaceRegion(*this, STC);
|
||||
return R;
|
||||
}
|
||||
|
||||
|
@ -781,7 +798,7 @@ const GlobalsSpaceRegion
|
|||
return R;
|
||||
|
||||
R = A.Allocate<StaticGlobalSpaceRegion>();
|
||||
new (R) StaticGlobalSpaceRegion(this, CR);
|
||||
new (R) StaticGlobalSpaceRegion(*this, CR);
|
||||
return R;
|
||||
}
|
||||
|
||||
|
@ -850,7 +867,7 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
|
|||
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 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
|
|||
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 @@ RegionOffset MemRegion::getAsOffset() const {
|
|||
|
||||
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 @@ void BlockDataRegion::LazyInitializeReferencedVars() {
|
|||
return;
|
||||
}
|
||||
|
||||
MemRegionManager &MemMgr = *getMemRegionManager();
|
||||
MemRegionManager &MemMgr = getMemRegionManager();
|
||||
llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
|
||||
BumpVectorContext BC(A);
|
||||
|
||||
|
|
|
@ -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 @@ collectSubRegionBindings(SmallVectorImpl<BindingPair> &Bindings,
|
|||
|
||||
// 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 @@ DefinedOrUnknownSVal
|
|||
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();
|
||||
|
|
|
@ -329,7 +329,7 @@ QualType SymbolDerived::getType() const {
|
|||
}
|
||||
|
||||
QualType SymbolExtent::getType() const {
|
||||
ASTContext &Ctx = R->getMemRegionManager()->getContext();
|
||||
ASTContext &Ctx = R->getMemRegionManager().getContext();
|
||||
return Ctx.getSizeType();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue