diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-06-09 05:50:38 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-06-09 05:50:38 +0000 |
commit | 2c46458d4cd96a3a33e8810e95e692d8e2e05ff3 (patch) | |
tree | 98c9cf626d95a30a220ff61e59a275f9deeed31d /lib/Checker/StackAddrLeakChecker.cpp | |
parent | 95450f6ffc89ee218faa550433265f80930469c4 (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.cpp | 53 |
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); } - } + } } } } } } - |