[cfe-commits] r91107 - in /cfe/trunk: include/clang/Analysis/PathSensitive/AnalysisContext.h include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/AnalysisContext.cpp lib/Analysis/MemRegion.cpp lib/Analysis/RegionStore.cpp lib/Analysis/Store.cpp test/Analysis/misc-ps-region-store.m
Ted Kremenek
kremenek at apple.com
Thu Dec 10 22:43:28 PST 2009
Author: kremenek
Date: Fri Dec 11 00:43:27 2009
New Revision: 91107
URL: http://llvm.org/viewvc/llvm-project?rev=91107&view=rev
Log:
Enhance understanding of VarRegions referenced by a block whose declarations are outside the current stack frame. Fixes <rdar://problem/7462324>.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h
cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
cfe/trunk/lib/Analysis/AnalysisContext.cpp
cfe/trunk/lib/Analysis/MemRegion.cpp
cfe/trunk/lib/Analysis/RegionStore.cpp
cfe/trunk/lib/Analysis/Store.cpp
cfe/trunk/test/Analysis/misc-ps-region-store.m
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h Fri Dec 11 00:43:27 2009
@@ -120,6 +120,8 @@
}
const StackFrameContext *getCurrentStackFrame() const;
+ const StackFrameContext *
+ getStackFrameForDeclContext(const DeclContext *DC) const;
virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Fri Dec 11 00:43:27 2009
@@ -53,6 +53,7 @@
StackLocalsSpaceRegionKind,
StackArgumentsSpaceRegionKind,
HeapSpaceRegionKind,
+ UnknownSpaceRegionKind,
GlobalsSpaceRegionKind,
END_MEMSPACES = GlobalsSpaceRegionKind,
// Untyped regions.
@@ -171,6 +172,16 @@
}
};
+class UnknownSpaceRegion : public MemSpaceRegion {
+ friend class MemRegionManager;
+ UnknownSpaceRegion(MemRegionManager *mgr)
+ : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+public:
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == UnknownSpaceRegionKind;
+ }
+};
+
class StackSpaceRegion : public MemSpaceRegion {
private:
const StackFrameContext *SFC;
@@ -757,16 +768,23 @@
llvm::FoldingSet<MemRegion> Regions;
GlobalsSpaceRegion *globals;
- StackLocalsSpaceRegion *stackLocals;
- StackArgumentsSpaceRegion *stackArguments;
+
+ const StackFrameContext *cachedStackLocalsFrame;
+ StackLocalsSpaceRegion *cachedStackLocalsRegion;
+
+ const StackFrameContext *cachedStackArgumentsFrame;
+ StackArgumentsSpaceRegion *cachedStackArgumentsRegion;
+
HeapSpaceRegion *heap;
- MemSpaceRegion *unknown;
+ UnknownSpaceRegion *unknown;
MemSpaceRegion *code;
public:
MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
- : C(c), A(a), globals(0), stackLocals(0), stackArguments(0), heap(0),
- unknown(0), code(0) {}
+ : C(c), A(a), globals(0),
+ cachedStackLocalsFrame(0), cachedStackLocalsRegion(0),
+ cachedStackArgumentsFrame(0), cachedStackArgumentsRegion(0),
+ heap(0), unknown(0), code(0) {}
~MemRegionManager();
Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Fri Dec 11 00:43:27 2009
@@ -179,6 +179,19 @@
return NULL;
}
+const StackFrameContext *
+LocationContext::getStackFrameForDeclContext(const DeclContext *DC) const {
+ const LocationContext *LC = this;
+ while (LC) {
+ if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
+ if (cast<DeclContext>(SFC->getDecl()) == DC)
+ return SFC;
+ }
+ LC = LC->getParent();
+ }
+ return NULL;
+}
+
//===----------------------------------------------------------------------===//
// Lazily generated map to query the external variables referenced by a Block.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Fri Dec 11 00:43:27 2009
@@ -381,13 +381,22 @@
}
const StackLocalsSpaceRegion*
-MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
- return LazyAllocate(stackLocals, STC);
+MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
+ assert(STC);
+ if (STC == cachedStackLocalsFrame)
+ return cachedStackLocalsRegion;
+ cachedStackLocalsFrame = STC;
+ return LazyAllocate(cachedStackLocalsRegion, STC);
}
const StackArgumentsSpaceRegion *
MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
- return LazyAllocate(stackArguments, STC);
+ assert(STC);
+ if (STC == cachedStackArgumentsFrame)
+ return cachedStackArgumentsRegion;
+
+ cachedStackArgumentsFrame = STC;
+ return LazyAllocate(cachedStackArgumentsRegion, STC);
}
const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
@@ -418,15 +427,19 @@
const LocationContext *LC) {
const MemRegion *sReg = 0;
- if (D->hasLocalStorage()) {
+ if (D->hasLocalStorage()) {
// FIXME: Once we implement scope handling, we will need to properly lookup
// 'D' to the proper LocationContext.
- const StackFrameContext *STC = LC->getCurrentStackFrame();
+ const DeclContext *DC = D->getDeclContext();
+ const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
- assert(STC);
- sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
- ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
- : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+ if (!STC)
+ sReg = getUnknownRegion();
+ else {
+ sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+ ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+ : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+ }
}
else {
sReg = getGlobalsRegion();
Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Fri Dec 11 00:43:27 2009
@@ -728,6 +728,7 @@
case MemRegion::StackArgumentsSpaceRegionKind:
case MemRegion::HeapSpaceRegionKind:
case MemRegion::GlobalsSpaceRegionKind:
+ case MemRegion::UnknownSpaceRegionKind:
assert(0 && "Cannot index into a MemSpace");
return UnknownVal();
@@ -881,6 +882,7 @@
case MemRegion::StackArgumentsSpaceRegionKind:
case MemRegion::HeapSpaceRegionKind:
case MemRegion::GlobalsSpaceRegionKind:
+ case MemRegion::UnknownSpaceRegionKind:
assert(0 && "Cannot perform pointer arithmetic on a MemSpace");
return UnknownVal();
}
@@ -1292,7 +1294,8 @@
// Lazily derive a value for the VarRegion.
const VarDecl *VD = R->getDecl();
- if (R->hasGlobalsOrParametersStorage())
+ if (R->hasGlobalsOrParametersStorage() ||
+ isa<UnknownSpaceRegion>(R->getMemorySpace()))
return ValMgr.getRegionValueSymbolValOrUnknown(R, VD->getType());
return UndefinedVal();
Modified: cfe/trunk/lib/Analysis/Store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Store.cpp?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/Store.cpp (original)
+++ cfe/trunk/lib/Analysis/Store.cpp Fri Dec 11 00:43:27 2009
@@ -81,6 +81,7 @@
case MemRegion::StackLocalsSpaceRegionKind:
case MemRegion::StackArgumentsSpaceRegionKind:
case MemRegion::HeapSpaceRegionKind:
+ case MemRegion::UnknownSpaceRegionKind:
case MemRegion::GlobalsSpaceRegionKind: {
assert(0 && "Invalid region cast");
break;
Modified: cfe/trunk/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.m?rev=91107&r1=91106&r2=91107&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.m Fri Dec 11 00:43:27 2009
@@ -1,5 +1,5 @@
-// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s
-// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s
+// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
typedef struct objc_selector *SEL;
typedef signed char BOOL;
@@ -583,3 +583,38 @@
return z;
}
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7462324> - Test that variables passed using __blocks
+// are not treated as being uninitialized.
+//===----------------------------------------------------------------------===//
+
+typedef void (^RDar_7462324_Callback)(id obj);
+
+ at interface RDar7462324
+- (void) foo:(id)target;
+- (void) foo_positive:(id)target;
+
+ at end
+
+ at implementation RDar7462324
+- (void) foo:(id)target {
+ __block RDar_7462324_Callback builder = ((void*) 0);
+ builder = ^(id object) {
+ if (object) {
+ builder(self); // no-warning
+ }
+ };
+ builder(target);
+}
+- (void) foo_positive:(id)target {
+ __block RDar_7462324_Callback builder = ((void*) 0);
+ builder = ^(id object) {
+ id x;
+ if (object) {
+ builder(x); // expected-warning{{Pass-by-value argument in function call is undefined}}
+ }
+ };
+ builder(target);
+}
+ at end
+
More information about the cfe-commits
mailing list