From: Ted Kremenek Date: Fri, 28 Sep 2007 21:29:33 +0000 (+0000) Subject: Fixed bug where assignments to variables wrapped in parentheses would not X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bcb07d5d3f4e47b72f7a3a5f62b75b7dabe8c68d;p=clang 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 --- 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*>(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(S)) { S=P->getSubExpr(); continue;} - else if (DeclRefExpr* DR = dyn_cast(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(S)) { + S = P->getSubExpr(); continue; + } + else if (DeclRefExpr* DR = dyn_cast(S)) + return DR; + else + return NULL; +} + void TransferFuncs::VisitAssign(BinaryOperator* B) { Stmt* LHS = B->getLHS(); - if (DeclRefExpr* DR = dyn_cast(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);