[analyzer] Teach UndefOrNullArgVisitor to track parent regions.

llvm-svn: 163748
This commit is contained in:
Anna Zaks 2012-09-12 22:57:30 +00:00
parent 5297748e3f
commit e663b80975
4 changed files with 1183 additions and 426 deletions

View File

@ -140,6 +140,9 @@ public:
const MemRegion *getBaseRegion() const;
/// Check if the region is a subregion of the given region.
bool isSubRegionOf(const MemRegion *PR) const;
const MemRegion *StripCasts(bool StripBaseCasts = true) const;
bool hasGlobalsOrParametersStorage() const;

View File

@ -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;

View File

@ -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.
//===----------------------------------------------------------------------===//

File diff suppressed because it is too large Load Diff