diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r-- | lib/StaticAnalyzer/Core/MemRegion.cpp | 4 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SValBuilder.cpp | 12 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 43 |
3 files changed, 39 insertions, 20 deletions
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index 96905c081e..bcf7c3fe7d 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -849,6 +849,10 @@ const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { return getSubRegion<SymbolicRegion>(sym, getUnknownRegion()); } +const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { + return getSubRegion<SymbolicRegion>(Sym, getHeapRegion()); +} + const FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl *d, const MemRegion* superRegion){ diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index 765ae48c73..c391489beb 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -148,6 +148,18 @@ SValBuilder::getConjuredSymbolVal(const Stmt *stmt, return nonloc::SymbolVal(sym); } +DefinedOrUnknownSVal +SValBuilder::getConjuredHeapSymbolVal(const Expr *E, + const LocationContext *LCtx, + unsigned VisitCount) { + QualType T = E->getType(); + assert(Loc::isLocType(T)); + assert(SymbolManager::canSymbolicate(T)); + + SymbolRef sym = SymMgr.getConjuredSymbol(E, LCtx, T, VisitCount); + return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym)); +} + DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag, const MemRegion *region, const Expr *expr, QualType type, diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 29c65f8f3e..9cbbece98e 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -673,11 +673,18 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, // regions, though. return UnknownVal(); - // If both values wrap regions, see if they're from different base regions. + const MemSpaceRegion *LeftMS = LeftMR->getMemorySpace(); + const MemSpaceRegion *RightMS = RightMR->getMemorySpace(); + const MemSpaceRegion *UnknownMS = MemMgr.getUnknownRegion(); const MemRegion *LeftBase = LeftMR->getBaseRegion(); const MemRegion *RightBase = RightMR->getBaseRegion(); - if (LeftBase != RightBase && - !isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) { + + // If the two regions are from different known memory spaces they cannot be + // equal. Also, assume that no symbolic region (whose memory space is + // unknown) is on the stack. + if (LeftMS != RightMS && + ((LeftMS != UnknownMS && RightMS != UnknownMS) || + (isa<StackSpaceRegion>(LeftMS) || isa<StackSpaceRegion>(RightMS)))) { switch (op) { default: return UnknownVal(); @@ -688,24 +695,20 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state, } } - // The two regions are from the same base region. See if they're both a - // type of region we know how to compare. - const MemSpaceRegion *LeftMS = LeftBase->getMemorySpace(); - const MemSpaceRegion *RightMS = RightBase->getMemorySpace(); - - // Heuristic: assume that no symbolic region (whose memory space is - // unknown) is on the stack. - // FIXME: we should be able to be more precise once we can do better - // aliasing constraints for symbolic regions, but this is a reasonable, - // albeit unsound, assumption that holds most of the time. - if (isa<StackSpaceRegion>(LeftMS) ^ isa<StackSpaceRegion>(RightMS)) { + // If both values wrap regions, see if they're from different base regions. + // Note, heap base symbolic regions are assumed to not alias with + // each other; for example, we assume that malloc returns different address + // on each invocation. + if (LeftBase != RightBase && + ((!isa<SymbolicRegion>(LeftBase) && !isa<SymbolicRegion>(RightBase)) || + isa<HeapSpaceRegion>(LeftMS)) ){ switch (op) { - default: - break; - case BO_EQ: - return makeTruthVal(false, resultTy); - case BO_NE: - return makeTruthVal(true, resultTy); + default: + return UnknownVal(); + case BO_EQ: + return makeTruthVal(false, resultTy); + case BO_NE: + return makeTruthVal(true, resultTy); } } |