summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-09-12 22:57:30 +0000
committerAnna Zaks <ganna@apple.com>2012-09-12 22:57:30 +0000
commite663b80975b271696cdd5111dc243d93ed0077c5 (patch)
tree0525404931ca67c4bf3ffd814cfa24374cc31fd5 /clang/lib
parent5297748e3f964788d7defdbc1be5c927f334fb31 (diff)
downloadbcm5719-llvm-e663b80975b271696cdd5111dc243d93ed0077c5.tar.gz
bcm5719-llvm-e663b80975b271696cdd5111dc243d93ed0077c5.zip
[analyzer] Teach UndefOrNullArgVisitor to track parent regions.
llvm-svn: 163748
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp8
-rw-r--r--clang/lib/StaticAnalyzer/Core/MemRegion.cpp20
2 files changed, 25 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 0d0006c5eb2..be946842fc3 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -517,6 +517,8 @@ void bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
// However, if the rvalue is a symbolic region, we should track it as well.
SVal RVal = state->getSVal(L->getRegion());
const MemRegion *RegionRVal = RVal.getAsRegion();
+ report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
+
if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
report.markInteresting(RegionRVal);
@@ -985,8 +987,8 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
E = Call->param_end(); I != E; ++I, ++Idx) {
const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
- // Are we tracking the argument?
- if ( !ArgReg || ArgReg != R)
+ // Are we tracking the argument or its subregion?
+ if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
continue;
// Check the function parameter type.
@@ -1006,7 +1008,7 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
// Mark the call site (LocationContext) as interesting if the value of the
// argument is undefined or '0'/'NULL'.
- SVal BoundVal = State->getSVal(ArgReg);
+ SVal BoundVal = State->getSVal(R);
if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
BR.markInteresting(CEnter->getCalleeContext());
return 0;
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index b29327efcfc..6d6bb208185 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -990,6 +990,26 @@ const MemRegion *MemRegion::getBaseRegion() const {
return R;
}
+bool MemRegion::isSubRegionOf(const MemRegion *PR) const {
+ const MemRegion *R = this;
+ while (true) {
+ switch (R->getKind()) {
+ case MemRegion::ElementRegionKind:
+ case MemRegion::FieldRegionKind:
+ case MemRegion::ObjCIvarRegionKind:
+ case MemRegion::CXXBaseObjectRegionKind:
+ R = cast<SubRegion>(R)->getSuperRegion();
+ if (R == PR)
+ return true;
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// View handling.
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud