diff options
Diffstat (limited to 'Analysis/GRConstants.cpp')
-rw-r--r-- | Analysis/GRConstants.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 3eff0e0c86..1502fd4fb8 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -192,6 +192,8 @@ public: StateTy RemoveGrandchildrenMappings(Stmt* S, StateTy M); void AddBinding(Expr* E, ExprVariantTy V, bool isBlkLvl = false); + void AddBinding(Decl* D, ExprVariantTy V); + ExprVariantTy GetBinding(Expr* E); void BlockStmt_VisitStmt(Stmt* S) { DoStmt(S); } @@ -200,6 +202,7 @@ public: void VisitIntegerLiteral(IntegerLiteral* L); void VisitBinAdd(BinaryOperator* O); void VisitBinSub(BinaryOperator* O); + void VisitBinAssign(BinaryOperator* D); }; } // end anonymous namespace @@ -229,6 +232,13 @@ void GRConstants::AddBinding(Expr* E, ExprVariantTy V, bool isBlkLvl) { CurrentState = StateMgr.Add(CurrentState, DSPtr(E,isBlkLvl), V.getVal()); } +void GRConstants::AddBinding(Decl* D, ExprVariantTy V) { + if (V) + CurrentState = StateMgr.Add(CurrentState, DSPtr(D), V.getVal()); + else + CurrentState = StateMgr.Remove(CurrentState, DSPtr(D)); +} + void GRConstants::SwitchNodeSets() { NodeSetTy* Tmp = OldNodes; OldNodes = Nodes; @@ -290,6 +300,20 @@ void GRConstants::VisitBinSub(BinaryOperator* B) { AddBinding(B, GetBinding(B->getLHS()) - GetBinding(B->getRHS())); } + +static inline Expr* IgnoreParen(Expr* E) { + while (ParenExpr* P = dyn_cast<ParenExpr>(E)) + E = P->getSubExpr(); + + return E; +} + + +void GRConstants::VisitBinAssign(BinaryOperator* B) { + if (DeclRefExpr* D = dyn_cast<DeclRefExpr>(IgnoreParen(B->getLHS()))) + AddBinding(D->getDecl(), GetBinding(B->getRHS())); +} + //===----------------------------------------------------------------------===// // Driver. //===----------------------------------------------------------------------===// |