Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[analyzer] Look for calls along with lvalue nodes in trackNullOrUndef…
Browse files Browse the repository at this point in the history
…Value.

r176737 fixed bugreporter::trackNullOrUndefValue to find nodes for an lvalue
even if the rvalue node had already been collected. This commit extends that
to call statement nodes as well, so that if a call is contained within
implicit casts we can still track the return value.

No test case because node reclamation is extremely finicky (dependent on
how the AST and CFG are built, and then on our current reclamation rules,
and /then/ on how many nodes were generated by the analyzer core and the
current set of checkers). I consider this a low-risk change, though, and
it will only happen in cases of reclamation when the rvalue node isn't
available.

<rdar://problem/13340764>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176829 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
jrose-apple committed Mar 11, 2013
1 parent ebf0f43 commit 77b7223
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,11 +767,11 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *ErrorNode,

const ExplodedNode *N = ErrorNode;

const Expr *LValue = 0;
const Expr *Inner = 0;
if (const Expr *Ex = dyn_cast<Expr>(S)) {
Ex = Ex->IgnoreParenCasts();
if (ExplodedGraph::isInterestingLValueExpr(Ex))
LValue = Ex;
if (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex))
Inner = Ex;
}

if (IsArg) {
Expand All @@ -783,10 +783,11 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *ErrorNode,
do {
const ProgramPoint &pp = N->getLocation();
if (Optional<PostStmt> ps = pp.getAs<PostStmt>()) {
if (ps->getStmt() == S || ps->getStmt() == LValue)
if (ps->getStmt() == S || ps->getStmt() == Inner)
break;
} else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
if (CEE->getCalleeContext()->getCallSite() == S)
if (CEE->getCalleeContext()->getCallSite() == S ||
CEE->getCalleeContext()->getCallSite() == Inner)
break;
}
N = N->getFirstPred();
Expand All @@ -800,12 +801,12 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *ErrorNode,

// See if the expression we're interested refers to a variable.
// If so, we can track both its contents and constraints on its value.
if (LValue) {
if (Inner && ExplodedGraph::isInterestingLValueExpr(Inner)) {
const MemRegion *R = 0;

// First check if this is a DeclRefExpr for a C++ reference type.
// For those, we want the location of the reference.
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LValue)) {
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Inner)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
if (VD->getType()->isReferenceType()) {
ProgramStateManager &StateMgr = state->getStateManager();
Expand All @@ -822,14 +823,14 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *ErrorNode,
const ExplodedNode *LVNode = N;
while (LVNode) {
if (Optional<PostStmt> P = LVNode->getLocation().getAs<PostStmt>()) {
if (P->getStmt() == LValue)
if (P->getStmt() == Inner)
break;
}
LVNode = LVNode->getFirstPred();
}
assert(LVNode && "Unable to find the lvalue node.");
ProgramStateRef LVState = LVNode->getState();
R = LVState->getSVal(LValue, LVNode->getLocationContext()).getAsRegion();
R = LVState->getSVal(Inner, LVNode->getLocationContext()).getAsRegion();
}

if (R) {
Expand Down

0 comments on commit 77b7223

Please sign in to comment.