diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-11-21 00:27:44 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-11-21 00:27:44 +0000 |
commit | 5917d7894e8274b9625275dd4dd86c5d0040a242 (patch) | |
tree | 09c3178478323c166af19f8a16b96037f5dc42d4 | |
parent | 9f49055456049bdff41f61231553d29573fac184 (diff) |
- Clean up transfer function logic for 'return' statements.
- Add check for returning an undefined value to a caller.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59764 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 9 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 62 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 14 |
3 files changed, 47 insertions, 38 deletions
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 9ab4f4fddc..5ba61d8645 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -104,12 +104,17 @@ public: typedef llvm::SmallPtrSet<NodeTy*,2> NoReturnCallsTy; typedef llvm::SmallPtrSet<NodeTy*,2> UndefResultsTy; typedef llvm::SmallPtrSet<NodeTy*,2> RetsStackAddrTy; + typedef llvm::SmallPtrSet<NodeTy*,2> RetsUndefTy; protected: /// RetsStackAddr - Nodes in the ExplodedGraph that result from returning /// the address of a stack variable. RetsStackAddrTy RetsStackAddr; + + /// RetsUndef - Nodes in the ExplodedGraph that result from returning + /// an undefined value. + RetsUndefTy RetsUndef; /// UndefBranches - Nodes in the ExplodedGraph that result from /// taking a branch based on an undefined value. @@ -288,6 +293,10 @@ public: ret_stackaddr_iterator ret_stackaddr_begin() { return RetsStackAddr.begin(); } ret_stackaddr_iterator ret_stackaddr_end() { return RetsStackAddr.end(); } + typedef RetsUndefTy::iterator ret_undef_iterator; + ret_undef_iterator ret_undef_begin() { return RetsUndef.begin(); } + ret_undef_iterator ret_undef_end() { return RetsUndef.end(); } + typedef UndefBranchesTy::iterator undef_branch_iterator; undef_branch_iterator undef_branches_begin() { return UndefBranches.begin(); } undef_branch_iterator undef_branches_end() { return UndefBranches.end(); } diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index fe7d6f9426..db325fb9f9 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -2246,47 +2246,37 @@ void GRExprEngine::VisitReturnStmt(ReturnStmt* S, NodeTy* Pred, NodeSet& Dst) { return; } - NodeSet DstRet; - QualType T = R->getType(); - - if (T->isPointerLikeType()) { - - // Check if any of the return values return the address of a stack variable. - - NodeSet Tmp; - Visit(R, Pred, Tmp); - - for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { - SVal X = GetSVal((*I)->getState(), R); - - if (isa<loc::MemRegionVal>(X)) { - - // Determine if the value is on the stack. - const MemRegion* R = cast<loc::MemRegionVal>(&X)->getRegion(); + NodeSet Tmp; + Visit(R, Pred, Tmp); - if (R && getStateManager().hasStackStorage(R)) { - - // Create a special node representing the v - - NodeTy* RetStackNode = Builder->generateNode(S, GetState(*I), *I); - - if (RetStackNode) { - RetStackNode->markAsSink(); - RetsStackAddr.insert(RetStackNode); - } - - continue; + for (NodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { + SVal X = GetSVal((*I)->getState(), R); + + // Check if we return the address of a stack variable. + if (isa<loc::MemRegionVal>(X)) { + // Determine if the value is on the stack. + const MemRegion* R = cast<loc::MemRegionVal>(&X)->getRegion(); + + if (R && getStateManager().hasStackStorage(R)) { + // Create a special node representing the error. + if (NodeTy* N = Builder->generateNode(S, GetState(*I), *I)) { + N->markAsSink(); + RetsStackAddr.insert(N); } + continue; } - - DstRet.Add(*I); } - } - else - Visit(R, Pred, DstRet); - - for (NodeSet::iterator I=DstRet.begin(), E=DstRet.end(); I!=E; ++I) + // Check if we return an undefined value. + else if (X.isUndef()) { + if (NodeTy* N = Builder->generateNode(S, GetState(*I), *I)) { + N->markAsSink(); + RetsUndef.insert(N); + } + continue; + } + EvalReturn(Dst, S, *I); + } } //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index cc5762267b..b4d4cb2c56 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -180,7 +180,7 @@ public: } } }; - + class VISIBILITY_HIDDEN RetStack : public BuiltinBug { public: RetStack() : BuiltinBug("return of stack address") {} @@ -239,7 +239,16 @@ public: } } }; - + +class VISIBILITY_HIDDEN RetUndef : public BuiltinBug { +public: + RetUndef() : BuiltinBug("uninitialized return value", + "Uninitialized or undefined return value returned to caller.") {} + + virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) { + Emit(BR, Eng.ret_undef_begin(), Eng.ret_undef_end()); + } +}; class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug { struct VISIBILITY_HIDDEN FindUndefExpr { @@ -379,6 +388,7 @@ void GRExprEngine::RegisterInternalChecks() { Register(new UndefResult()); Register(new BadCall()); Register(new RetStack()); + Register(new RetUndef()); Register(new BadArg()); Register(new BadMsgExprArg()); Register(new BadReceiver()); |