aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-03-11 21:31:46 +0000
committerJordan Rose <jordan_rose@apple.com>2013-03-11 21:31:46 +0000
commit77b72231a0316509cc939b052be35fafce606567 (patch)
tree8292387c3649a156dbe64037bc42f44f085b272e
parentebf0f43f07e2fdc0e35554afb38f41c8be314b02 (diff)
[analyzer] Look for calls along with lvalue nodes in trackNullOrUndefValue.
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
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp19
1 files changed, 10 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 88e4ba5876..517c1a10f8 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -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) {
@@ -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();
@@ -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();
@@ -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) {