ariccio created this revision.
ariccio added reviewers: aaron.ballman, dcoughlin.
ariccio added a subscriber: cfe-commits.
Instead of one long function, `MemRegionManager::getVarRegion` now calls
`getMemRegionGloballyStored` for global, non-static variables, and
`getMemRegionStaticLocal` for static locals. The behavior of
`MemRegionManager::getVarRegion` is thus clearer, and easier to reason about.
http://reviews.llvm.org/D16873
Files:
llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Index: llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
===================================================================
--- llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1180,6 +1180,16 @@
/// a specified VarDecl and LocationContext.
const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
+private:
+ /// getMemRegionGloballyStored - Retrieve or create the memory region
+ /// associated with a specified globally stored, non-static local, VarDecl.
+ const MemRegion *getMemRegionGloballyStored(const VarDecl *D);
+
+ /// getMemRegionStaticLocal - Retrieve or create the memory region
+ /// associated with a specified VarDecl and LocationContext.
+ const MemRegion *getMemRegionStaticLocal(const VarDecl *D, const LocationContext *LC);
+
+public:
/// getVarRegion - Retrieve or create the memory region associated with
/// a specified VarDecl and super region.
const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
Index: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -766,87 +766,89 @@
return (const StackFrameContext *)nullptr;
}
-const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
- const LocationContext *LC) {
- const MemRegion *sReg = nullptr;
+const MemRegion* MemRegionManager::getMemRegionGloballyStored(const VarDecl *D) {
+ assert(D->hasGlobalStorage());
+ assert(!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)
+ return getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
- if (D->hasGlobalStorage() && !D->isStaticLocal()) {
+ return getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
+ }
+ // Treat other globals as GlobalInternal unless they are constants.
+ 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())
+ return getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
- // 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);
+ return getGlobalsRegion();
+}
- // 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();
- }
+const MemRegion* MemRegionManager::getMemRegionStaticLocal(const VarDecl *D, const LocationContext *LC) {
+ // FIXME: Once we implement scope handling, we will need to properly lookup
+ // 'D' to the proper LocationContext.
+ const DeclContext *DC = D->getDeclContext();
+ llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
+ getStackOrCaptureRegionForDeclContext(LC, DC, D);
- // 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();
- llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
- getStackOrCaptureRegionForDeclContext(LC, DC, D);
+ if (V.is<const VarRegion*>())
+ return V.get<const VarRegion*>();
- if (V.is<const VarRegion*>())
- return V.get<const VarRegion*>();
+ const StackFrameContext *STC = V.get<const StackFrameContext*>();
- const StackFrameContext *STC = V.get<const StackFrameContext*>();
+ if (!STC)
+ return getUnknownRegion();
- if (!STC)
- sReg = getUnknownRegion();
- else {
- if (D->hasLocalStorage()) {
- sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
- ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
- : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
- }
- else {
- assert(D->isStaticLocal());
- const Decl *STCD = STC->getDecl();
- if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
- sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
- getFunctionCodeRegion(cast<NamedDecl>(STCD)));
- else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
- // FIXME: The fallback type here is totally bogus -- though it should
- // never be queried, it will prevent uniquing with the real
- // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
- // signature.
- QualType T;
- if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
- T = TSI->getType();
- if (T.isNull())
- T = getContext().VoidTy;
- if (!T->getAs<FunctionType>())
- T = getContext().getFunctionNoProtoType(T);
- T = getContext().getBlockPointerType(T);
+ if (D->hasLocalStorage()) {
+ return (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+ ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+ : static_cast<const MemRegion*>(getStackLocalsRegion(STC)));
+ }
+ assert(D->isStaticLocal());
+ const Decl *STCD = STC->getDecl();
+ if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
+ return getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
+ getFunctionCodeRegion(cast<NamedDecl>(STCD)));
- const BlockCodeRegion *BTR =
- getBlockCodeRegion(BD, C.getCanonicalType(T),
- STC->getAnalysisDeclContext());
- sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
- BTR);
- }
- else {
- sReg = getGlobalsRegion();
- }
- }
- }
+ else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
+ // FIXME: The fallback type here is totally bogus -- though it should
+ // never be queried, it will prevent uniquing with the real
+ // BlockCodeRegion. Ideally we'd fix the AST so that we always had a
+ // signature.
+ QualType T;
+ if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten())
+ T = TSI->getType();
+ if (T.isNull())
+ T = getContext().VoidTy;
+ if (!T->getAs<FunctionType>())
+ T = getContext().getFunctionNoProtoType(T);
+ T = getContext().getBlockPointerType(T);
+
+ const BlockCodeRegion *BTR =
+ getBlockCodeRegion(BD, C.getCanonicalType(T),
+ STC->getAnalysisDeclContext());
+ return getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
+ BTR);
}
+ return getGlobalsRegion();
+}
+const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
+ const LocationContext *LC) {
+ const MemRegion *sReg = nullptr;
+
+ if (D->hasGlobalStorage() && !D->isStaticLocal()) {
+ sReg = getMemRegionGloballyStored(D);
+
+ // Finally handle static locals.
+ } else {
+ sReg = getMemRegionStaticLocal(D, LC);
+ }
return getSubRegion<VarRegion>(D, sReg);
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits