From 5b6dc2d72bf1bcf2b61fe5dbcd57bfa4aee76b29 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 7 Feb 2008 01:08:27 +0000 Subject: [PATCH] Added transfer function logic for ReturnStmts. Fixed insidious bug in handling dereferences. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46835 91177308-0d34-0410-b5e6-96231b3b80d8 --- Analysis/GRConstants.cpp | 39 +++++++++++++++++++++++++++++++++++++-- Analysis/RValues.cpp | 4 +++- Analysis/RValues.h | 4 ++-- Analysis/ValueState.cpp | 4 ++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 516af280f4..65cb6e76e8 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -256,6 +256,8 @@ public: /// VisitBinaryOperator - Transfer function logic for binary operators. void VisitBinaryOperator(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst); + void VisitAssignmentLHS(Expr* E, NodeTy* Pred, NodeSet& Dst); + /// VisitDeclStmt - Transfer function logic for DeclStmts. void VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst); @@ -671,7 +673,7 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, } case UnaryOperator::Deref: { - const LValue& L1 = GetLValue(St, U->getSubExpr()); + const LValue& L1 = cast(GetValue(St, U->getSubExpr())); Nodify(Dst, U, N1, SetValue(St, U, GetValue(St, L1))); break; } @@ -682,11 +684,31 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, } } +void GRConstants::VisitAssignmentLHS(Expr* E, GRConstants::NodeTy* Pred, + GRConstants::NodeSet& Dst) { + + if (isa(E)) + return; + + if (UnaryOperator* U = dyn_cast(E)) { + if (U->getOpcode() == UnaryOperator::Deref) { + Visit(U->getSubExpr(), Pred, Dst); + return; + } + } + + Visit(E, Pred, Dst); +} + void GRConstants::VisitBinaryOperator(BinaryOperator* B, GRConstants::NodeTy* Pred, GRConstants::NodeSet& Dst) { NodeSet S1; - Visit(B->getLHS(), Pred, S1); + + if (B->isAssignmentOp()) + VisitAssignmentLHS(B->getLHS(), Pred, S1); + else + Visit(B->getLHS(), Pred, S1); for (NodeSet::iterator I1=S1.begin(), E1=S1.end(); I1 != E1; ++I1) { NodeTy* N1 = *I1; @@ -712,6 +734,11 @@ void GRConstants::VisitBinaryOperator(BinaryOperator* B, if (Op <= BinaryOperator::Or) { + if (isa(V1) || isa(V1)) { + Nodify(Dst, B, N2, SetValue(St, B, V1)); + continue; + } + if (isa(V1)) { // FIXME: Add support for RHS being a non-lvalue. const LValue& L1 = cast(V1); @@ -824,6 +851,14 @@ void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred, break; } + case Stmt::ReturnStmtClass: + if (Expr* R = cast(S)->getRetValue()) + Visit(R, Pred, Dst); + else + Dst.Add(Pred); + + break; + case Stmt::DeclStmtClass: VisitDeclStmt(cast(S), Pred, Dst); break; diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp index bf6a0afdfd..bfdfe3bf45 100644 --- a/Analysis/RValues.cpp +++ b/Analysis/RValues.cpp @@ -481,7 +481,9 @@ RValue RValue::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) { return nonlval::SymbolVal(SymMgr.getSymbol(D)); } - +void RValue::print() const { + print(*llvm::cerr.stream()); +} //===----------------------------------------------------------------------===// // Pretty-Printing. diff --git a/Analysis/RValues.h b/Analysis/RValues.h index 01df7dcd48..19ebbd4b4c 100644 --- a/Analysis/RValues.h +++ b/Analysis/RValues.h @@ -260,7 +260,7 @@ public: inline bool isInvalid() const { return getRawKind() == InvalidKind; } void print(std::ostream& OS) const; - void print() const { print(*llvm::cerr.stream()); } + void print() const; // Implement isa support. static inline bool classof(const RValue*) { return true; } @@ -323,7 +323,7 @@ protected: NonLValue NE(ValueManager& ValMgr, const LValue& RHS) const; public: - void print(std::ostream& Out) const; +// void print(std::ostream& Out) const; RValue EvalBinaryOp(ValueManager& ValMgr, BinaryOperator::Opcode Op, const LValue& RHS) const; diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp index 00b6607536..1b08d8ea39 100644 --- a/Analysis/ValueState.cpp +++ b/Analysis/ValueState.cpp @@ -155,6 +155,10 @@ LValue ValueStateManager::GetLValue(const StateTy& St, Stmt* S) { if (DeclRefExpr* DR = dyn_cast(S)) return lval::DeclVal(DR->getDecl()); + if (UnaryOperator* U = dyn_cast(S)) + if (U->getOpcode() == UnaryOperator::Deref) + return cast(GetValue(St, U->getSubExpr())); + return cast(GetValue(St, S)); } -- 2.40.0