aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp61
1 files changed, 26 insertions, 35 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 90bd0f31a5..1ba46ea067 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -40,33 +40,42 @@ using llvm::Optional;
namespace {
class BindingKey {
public:
- enum Kind { Direct = 0x0, Default = 0x1 };
+ enum Kind { Default = 0x0, Direct = 0x1 };
private:
- enum { SYMBOLIC = UINT64_MAX };
+ enum { Symbolic = 0x2 };
- llvm::PointerIntPair<const MemRegion *, 1, Kind> P;
- uint64_t Offset;
+ llvm::PointerIntPair<const MemRegion *, 2> P;
+ uint64_t Data;
- explicit BindingKey(const MemRegion *r, Kind k)
- : P(r, k), Offset(SYMBOLIC) {}
+ explicit BindingKey(const MemRegion *r, const MemRegion *Base, Kind k)
+ : P(r, k | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) {
+ assert(r && Base && "Must have known regions.");
+ assert(getConcreteOffsetRegion() == Base && "Failed to store base region");
+ }
explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k)
- : P(r, k), Offset(offset) {}
+ : P(r, k), Data(offset) {
+ assert(r && "Must have known regions.");
+ assert(getOffset() == offset && "Failed to store offset");
+ }
public:
- bool isDirect() const { return P.getInt() == Direct; }
- bool hasSymbolicOffset() const { return Offset == SYMBOLIC; }
+ bool isDirect() const { return P.getInt() & Direct; }
+ bool hasSymbolicOffset() const { return P.getInt() & Symbolic; }
const MemRegion *getRegion() const { return P.getPointer(); }
uint64_t getOffset() const {
assert(!hasSymbolicOffset());
- return Offset;
+ return Data;
}
- const MemRegion *getConcreteOffsetRegion() const;
+ const MemRegion *getConcreteOffsetRegion() const {
+ assert(hasSymbolicOffset());
+ return reinterpret_cast<const MemRegion *>(static_cast<uintptr_t>(Data));
+ }
void Profile(llvm::FoldingSetNodeID& ID) const {
ID.AddPointer(P.getOpaqueValue());
- ID.AddInteger(Offset);
+ ID.AddInteger(Data);
}
static BindingKey Make(const MemRegion *R, Kind k);
@@ -76,12 +85,12 @@ public:
return true;
if (P.getOpaqueValue() > X.P.getOpaqueValue())
return false;
- return Offset < X.Offset;
+ return Data < X.Data;
}
bool operator==(const BindingKey &X) const {
return P.getOpaqueValue() == X.P.getOpaqueValue() &&
- Offset == X.Offset;
+ Data == X.Data;
}
bool isValid() const {
@@ -92,27 +101,10 @@ public:
BindingKey BindingKey::Make(const MemRegion *R, Kind k) {
const RegionOffset &RO = R->getAsOffset();
- if (RO.isValid())
- return BindingKey(RO.getRegion(), RO.getOffset(), k);
-
- return BindingKey(R, k);
-}
-
-const MemRegion *BindingKey::getConcreteOffsetRegion() const {
- const MemRegion *R = getRegion();
- if (!hasSymbolicOffset())
- return R;
-
- RegionOffset RO;
- do {
- const SubRegion *SR = dyn_cast<SubRegion>(R);
- if (!SR)
- break;
- R = SR->getSuperRegion();
- RO = R->getAsOffset();
- } while (!RO.isValid());
+ if (RO.hasSymbolicOffset())
+ return BindingKey(R, RO.getRegion(), k);
- return R;
+ return BindingKey(RO.getRegion(), RO.getOffset(), k);
}
namespace llvm {
@@ -561,7 +553,6 @@ RegionBindings RegionStoreManager::removeSubRegionBindings(RegionBindings B,
// by changing the data structure used for RegionBindings.
BindingKey SRKey = BindingKey::Make(R, BindingKey::Default);
- assert(SRKey.isValid());
if (SRKey.hasSymbolicOffset()) {
const SubRegion *Base = cast<SubRegion>(SRKey.getConcreteOffsetRegion());
B = removeSubRegionBindings(B, Base);