From 5a7b3821c6abed7f58a53a94eac128bd23d23289 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 26 Feb 2008 23:37:01 +0000 Subject: [PATCH] Fix bug when processing '?' operator: invalidate the old "Uninitialized" value of the block-level expression for ?. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47645 91177308-0d34-0410-b5e6-96231b3b80d8 --- Analysis/GRExprEngine.cpp | 6 +++-- Analysis/ValueState.cpp | 23 +++++++++++++++---- Analysis/ValueState.h | 4 +++- .../Analysis/PathSensitive/GRExprEngine.h | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp index 674454c7cd..c911064b99 100644 --- a/Analysis/GRExprEngine.cpp +++ b/Analysis/GRExprEngine.cpp @@ -40,7 +40,7 @@ GRExprEngine::SetRVal(StateTy St, Expr* Ex, const RVal& V) { return St; } - return StateMgr.SetRVal(St, Ex, isBlkExpr, V); + return StateMgr.SetRVal(St, Ex, V, isBlkExpr, false); } const GRExprEngine::StateTy::BufferTy& @@ -606,7 +606,9 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R, assert (SE); X = GetBlkExprRVal(St, SE); - Nodify(Dst, Ex, Pred, SetBlkExprRVal(St, Ex, X)); + + // Make sure that we invalidate the previous binding. + Nodify(Dst, Ex, Pred, StateMgr.SetRVal(St, Ex, X, true, true)); } /// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type). diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp index 7be59ce5f5..97a090dad7 100644 --- a/Analysis/ValueState.cpp +++ b/Analysis/ValueState.cpp @@ -387,12 +387,27 @@ RVal ValueStateManager::GetLVal(ValueState St, Expr* E) { } ValueState -ValueStateManager::SetRVal(ValueState St, Expr* E, bool isBlkExpr, RVal V) { +ValueStateManager::SetRVal(ValueState St, Expr* E, RVal V, + bool isBlkExpr, bool Invalidate) { assert (E); - if (V.isUnknown()) + if (V.isUnknown()) { + + if (Invalidate) { + + ValueStateImpl NewSt = *St; + + if (isBlkExpr) + NewSt.BlockExprBindings = EXFactory.Remove(NewSt.BlockExprBindings, E); + else + NewSt.SubExprBindings = EXFactory.Remove(NewSt.SubExprBindings, E); + + return getPersistentState(NewSt); + } + return St; + } ValueStateImpl NewSt = *St; @@ -406,8 +421,8 @@ ValueStateManager::SetRVal(ValueState St, Expr* E, bool isBlkExpr, RVal V) { return getPersistentState(NewSt); } -ValueState -ValueStateManager::SetRVal(ValueState St, LVal LV, RVal V) { + +ValueState ValueStateManager::SetRVal(ValueState St, LVal LV, RVal V) { switch (LV.getSubKind()) { diff --git a/Analysis/ValueState.h b/Analysis/ValueState.h index 3e0012287b..5458ab86e5 100644 --- a/Analysis/ValueState.h +++ b/Analysis/ValueState.h @@ -255,7 +255,9 @@ public: return getPersistentState(NewSt); } - ValueState SetRVal(ValueState St, Expr* E, bool isBlkExpr, RVal V); + ValueState SetRVal(ValueState St, Expr* E, RVal V, + bool isBlkExpr, bool Invalidate); + ValueState SetRVal(ValueState St, LVal LV, RVal V); RVal GetRVal(ValueState St, Expr* E); diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 5c9092943b..4945f3107a 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -243,7 +243,7 @@ protected: } StateTy SetBlkExprRVal(StateTy St, Expr* Ex, const RVal& V) { - return StateMgr.SetRVal(St, Ex, true, V); + return StateMgr.SetRVal(St, Ex, V, true, false); } /// SetRVal - This version of SetRVal is used to batch process a set