diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/MemRegion.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/MemRegion.cpp | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index 2ddaed5b05..8af0251ee6 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -19,6 +19,7 @@ #include "clang/Analysis/Support/BumpVector.h" #include "clang/AST/CharUnits.h" #include "clang/AST/RecordLayout.h" +#include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -459,10 +460,6 @@ void FieldRegion::dumpToStream(raw_ostream &os) const { os << superRegion << "->" << *getDecl(); } -void NonStaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const { - os << "NonStaticGlobalSpaceRegion"; -} - void ObjCIvarRegion::dumpToStream(raw_ostream &os) const { os << "ivar{" << superRegion << ',' << *getDecl() << '}'; } @@ -491,6 +488,22 @@ void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const { os << "StaticGlobalsMemSpace{" << CR << '}'; } +void NonStaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const { + os << "NonStaticGlobalSpaceRegion"; +} + +void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const { + os << "GlobalInternalSpaceRegion"; +} + +void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const { + os << "GlobalSystemSpaceRegion"; +} + +void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const { + os << "GlobalImmutableSpaceRegion"; +} + //===----------------------------------------------------------------------===// // MemRegionManager methods. //===----------------------------------------------------------------------===// @@ -542,10 +555,18 @@ MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { } const GlobalsSpaceRegion -*MemRegionManager::getGlobalsRegion(const CodeTextRegion *CR) { - if (!CR) - return LazyAllocate(globals); +*MemRegionManager::getGlobalsRegion(MemRegion::Kind K, + const CodeTextRegion *CR) { + if (!CR) { + if (K == MemRegion::GlobalSystemSpaceRegionKind) + return LazyAllocate(SystemGlobals); + if (K == MemRegion::GlobalImmutableSpaceRegionKind) + return LazyAllocate(ImmutableGlobals); + assert(K == MemRegion::GlobalInternalSpaceRegionKind); + return LazyAllocate(InternalGlobals); + } + assert(K == MemRegion::StaticGlobalSpaceRegionKind); StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR]; if (R) return R; @@ -570,7 +591,6 @@ const MemSpaceRegion *MemRegionManager::getCodeRegion() { //===----------------------------------------------------------------------===// // Constructing regions. //===----------------------------------------------------------------------===// - const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){ return getSubRegion<StringRegion>(Str, getGlobalsRegion()); } @@ -579,9 +599,31 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, const LocationContext *LC) { const MemRegion *sReg = 0; - if (D->hasGlobalStorage() && !D->isStaticLocal()) - sReg = getGlobalsRegion(); - else { + if (D->hasGlobalStorage() && !D->isStaticLocal()) { + + // First handle the globals defined in system headers. + if (C.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) + sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); + else + sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); + + // Treat other globals as GlobalInternal unless they are constants. + } else { + QualType GQT = D->getType(); + const Type *GT = GQT.getTypePtrOrNull(); + // TODO: We could walk the complex types here and see if everything is + // constified. + if (GT && GQT.isConstQualified() && GT->isArithmeticType()) + sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); + else + sReg = getGlobalsRegion(); + } + + // Finally handle static locals. + } else { // FIXME: Once we implement scope handling, we will need to properly lookup // 'D' to the proper LocationContext. const DeclContext *DC = D->getDeclContext(); @@ -599,13 +641,15 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, assert(D->isStaticLocal()); const Decl *D = STC->getDecl(); if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - sReg = getGlobalsRegion(getFunctionTextRegion(FD)); + sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, + getFunctionTextRegion(FD)); else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { const BlockTextRegion *BTR = getBlockTextRegion(BD, C.getCanonicalType(BD->getSignatureAsWritten()->getType()), STC->getAnalysisDeclContext()); - sReg = getGlobalsRegion(BTR); + sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, + BTR); } else { // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now |