aboutsummaryrefslogtreecommitdiff
path: root/Analysis/LiveVariables.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2007-09-28 21:29:33 +0000
committerTed Kremenek <kremenek@apple.com>2007-09-28 21:29:33 +0000
commitbcb07d5d3f4e47b72f7a3a5f62b75b7dabe8c68d (patch)
treeba9e487160fd8bf06893562cf34044c9618b33b2 /Analysis/LiveVariables.cpp
parent6ce2b630652911c5b463ce0203855b1eaf4694bd (diff)
Fixed bug where assignments to variables wrapped in parentheses would not
properly kill variables. e.g: (x) = 1; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/LiveVariables.cpp')
-rw-r--r--Analysis/LiveVariables.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/Analysis/LiveVariables.cpp b/Analysis/LiveVariables.cpp
index d40941d13b..f8c3d378d9 100644
--- a/Analysis/LiveVariables.cpp
+++ b/Analysis/LiveVariables.cpp
@@ -73,6 +73,8 @@ public:
void VisitStmt(Stmt* S);
void BlockStmt_VisitExpr(Expr *E);
+ DeclRefExpr* FindDeclRef(Stmt *S);
+
void Visit(Stmt *S) {
if (AD.Observer) AD.Observer->ObserveStmt(S,AD,LiveState);
static_cast<CFGStmtVisitor<TransferFuncs>*>(this)->Visit(S);
@@ -91,6 +93,8 @@ void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
}
void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
+ Stmt *S = U->getSubExpr();
+
switch (U->getOpcode()) {
case UnaryOperator::PostInc:
case UnaryOperator::PostDec:
@@ -100,34 +104,43 @@ void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
// Walk through the subexpressions, blasting through ParenExprs
// until we either find a DeclRefExpr or some non-DeclRefExpr
// expression.
- for (Stmt* S = U->getSubExpr() ;;) {
- if (ParenExpr* P = dyn_cast<ParenExpr>(S)) { S=P->getSubExpr(); continue;}
- else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S)) {
- // Treat the --/++/& operator as a kill.
- LiveState(DR->getDecl(),AD) = Dead;
- if (AD.Observer) { AD.Observer->ObserverKill(DR); }
- return VisitDeclRefExpr(DR);
- }
- else return Visit(S);
+ if (DeclRefExpr* DR = FindDeclRef(S)) {
+ // Treat the --/++/& operator as a kill.
+ LiveState(DR->getDecl(),AD) = Dead;
+ if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+ return VisitDeclRefExpr(DR);
}
-
- assert (false && "Unreachable.");
+
+ // Fall-through.
default:
- return Visit(U->getSubExpr());
+ return Visit(S);
}
}
+DeclRefExpr* TransferFuncs::FindDeclRef(Stmt *S) {
+ for (;;)
+ if (ParenExpr* P = dyn_cast<ParenExpr>(S)) {
+ S = P->getSubExpr(); continue;
+ }
+ else if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(S))
+ return DR;
+ else
+ return NULL;
+}
+
void TransferFuncs::VisitAssign(BinaryOperator* B) {
Stmt* LHS = B->getLHS();
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) { // Assigning to a var?
+ // Assigning to a variable?
+ if (DeclRefExpr* DR = FindDeclRef(LHS)) {
LiveState(DR->getDecl(),AD) = Dead;
if (AD.Observer) { AD.Observer->ObserverKill(DR); }
// Handle things like +=, etc., which also generate "uses"
// of a variable. Do this just by visiting the subexpression.
- if (B->getOpcode() != BinaryOperator::Assign) Visit(LHS);
+ if (B->getOpcode() != BinaryOperator::Assign)
+ VisitDeclRefExpr(DR);
}
else // Not assigning to a variable. Process LHS as usual.
Visit(LHS);