aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Analysis/GRConstants.cpp39
-rw-r--r--Analysis/RValues.cpp4
-rw-r--r--Analysis/RValues.h4
-rw-r--r--Analysis/ValueState.cpp4
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<LValue>(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<DeclRefExpr>(E))
+ return;
+
+ if (UnaryOperator* U = dyn_cast<UnaryOperator>(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<InvalidValue>(V1) || isa<UninitializedValue>(V1)) {
+ Nodify(Dst, B, N2, SetValue(St, B, V1));
+ continue;
+ }
+
if (isa<LValue>(V1)) {
// FIXME: Add support for RHS being a non-lvalue.
const LValue& L1 = cast<LValue>(V1);
@@ -824,6 +851,14 @@ void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred,
break;
}
+ case Stmt::ReturnStmtClass:
+ if (Expr* R = cast<ReturnStmt>(S)->getRetValue())
+ Visit(R, Pred, Dst);
+ else
+ Dst.Add(Pred);
+
+ break;
+
case Stmt::DeclStmtClass:
VisitDeclStmt(cast<DeclStmt>(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<T> 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<DeclRefExpr>(S))
return lval::DeclVal(DR->getDecl());
+ if (UnaryOperator* U = dyn_cast<UnaryOperator>(S))
+ if (U->getOpcode() == UnaryOperator::Deref)
+ return cast<LValue>(GetValue(St, U->getSubExpr()));
+
return cast<LValue>(GetValue(St, S));
}