diff options
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r-- | clang/lib/Analysis/MemRegion.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Analysis/PointerSubChecker.cpp | 12 |
2 files changed, 27 insertions, 3 deletions
diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp index ad3d36e79d1..8c0b85c0c72 100644 --- a/clang/lib/Analysis/MemRegion.cpp +++ b/clang/lib/Analysis/MemRegion.cpp @@ -378,6 +378,24 @@ bool MemRegion::hasGlobalsOrParametersStorage() const { return false; } +// getBaseRegion strips away all elements and fields, and get the base region +// of them. +const MemRegion *MemRegion::getBaseRegion() const { + const MemRegion *R = this; + while (true) { + if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { + R = ER->getSuperRegion(); + continue; + } + if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) { + R = FR->getSuperRegion(); + continue; + } + break; + } + return R; +} + //===----------------------------------------------------------------------===// // View handling. //===----------------------------------------------------------------------===// diff --git a/clang/lib/Analysis/PointerSubChecker.cpp b/clang/lib/Analysis/PointerSubChecker.cpp index 5cac8aa99e7..20279c67b3e 100644 --- a/clang/lib/Analysis/PointerSubChecker.cpp +++ b/clang/lib/Analysis/PointerSubChecker.cpp @@ -48,11 +48,17 @@ void PointerSubChecker::PreVisitBinaryOperator(CheckerContext &C, const MemRegion *LR = LV.getAsRegion(); const MemRegion *RR = RV.getAsRegion(); - if (!(LR && RR) || (LR == RR)) + if (!(LR && RR)) return; - // We don't reason about SymbolicRegions for now. - if (isa<SymbolicRegion>(LR) || isa<SymbolicRegion>(RR)) + const MemRegion *BaseLR = LR->getBaseRegion(); + const MemRegion *BaseRR = RR->getBaseRegion(); + + if (BaseLR == BaseRR) + return; + + // Allow arithmetic on different symbolic regions. + if (isa<SymbolicRegion>(BaseLR) || isa<SymbolicRegion>(BaseRR)) return; if (ExplodedNode *N = C.GenerateNode(B)) { |