aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/StackAddrLeakChecker.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-06-09 05:50:38 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-06-09 05:50:38 +0000
commit2c46458d4cd96a3a33e8810e95e692d8e2e05ff3 (patch)
tree98c9cf626d95a30a220ff61e59a275f9deeed31d /lib/Checker/StackAddrLeakChecker.cpp
parent95450f6ffc89ee218faa550433265f80930469c4 (diff)
Directly compare the StackFrameContext. This greatly simplifies logic and
improves generality. Thanks Ted. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105686 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/StackAddrLeakChecker.cpp')
-rw-r--r--lib/Checker/StackAddrLeakChecker.cpp53
1 files changed, 23 insertions, 30 deletions
diff --git a/lib/Checker/StackAddrLeakChecker.cpp b/lib/Checker/StackAddrLeakChecker.cpp
index 0bd9e02448..8aa359e49e 100644
--- a/lib/Checker/StackAddrLeakChecker.cpp
+++ b/lib/Checker/StackAddrLeakChecker.cpp
@@ -54,41 +54,34 @@ void StackAddrLeakChecker::EvalEndPath(GREndPathNodeBuilder &B, void *tag,
SVal V = state->getSVal(cast<Loc>(L));
if (loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(&V)) {
const MemRegion *R = RV->getRegion();
- // Strip fields or elements to get the variable region.
- R = R->getBaseRegion();
- if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
- const VarDecl *VD = VR->getDecl();
- const DeclContext *DC = VD->getDeclContext();
- // Get the function where the variable is declared.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) {
- // Check if the function is the function we are leaving.
- if (FD == LCtx->getDecl()) {
- // The variable is declared in the function scope which we are
- // leaving. Keeping this variable's address in a global variable
- // is dangerous.
- // FIXME: Currently VarRegion does not carry context information.
- // So we cannot tell if the local variable instance is in the
- // current stack frame. This may produce false positive in
- // recursive function call context. But that's a rare case.
- // FIXME: better warning location.
+ if (const StackSpaceRegion *SSR =
+ dyn_cast<StackSpaceRegion>(R->getMemorySpace())) {
+ const StackFrameContext *ValSFC = SSR->getStackFrame();
+ const StackFrameContext *CurSFC = LCtx->getCurrentStackFrame();
+ // If the global variable holds a location in the current stack frame,
+ // emit a warning.
+ if (ValSFC == CurSFC) {
+ // The variable is declared in the function scope which we are
+ // leaving. Keeping this variable's address in a global variable
+ // is dangerous.
- ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
- if (N) {
- if (!BT_stackleak)
- BT_stackleak = new BuiltinBug("Stack address leak",
- "Stack address was saved into a global variable. "
- "This is dangerous because the address will become invalid "
- "after returning from the function.");
- BugReport *R = new BugReport(*BT_stackleak,
- BT_stackleak->getDescription(), N);
- Eng.getBugReporter().EmitReport(R);
- }
+ // FIXME: better warning location.
+
+ ExplodedNode *N = B.generateNode(state, tag, B.getPredecessor());
+ if (N) {
+ if (!BT_stackleak)
+ BT_stackleak = new BuiltinBug("Stack address leak",
+ "Stack address was saved into a global variable. "
+ "is dangerous because the address will become invalid "
+ "after returning from the function.");
+ BugReport *R = new BugReport(*BT_stackleak,
+ BT_stackleak->getDescription(), N);
+ Eng.getBugReporter().EmitReport(R);
}
- }
+ }
}
}
}
}
}
-