forked from OSchip/llvm-project
[analyzer] Teach UndefOrNullArgVisitor to track parent regions.
llvm-svn: 163748
This commit is contained in:
parent
5297748e3f
commit
e663b80975
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue