diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-06 00:30:00 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-06 00:30:00 +0000 |
commit | f91a5b008d1a63630ae483247204c2651e512fa1 (patch) | |
tree | d42b3e32a04c3addc59fdee74e93c0b0b96f216f /lib/Analysis/LiveVariables.cpp | |
parent | bea2753da897ede723e70bcd17023d050b0603d0 (diff) |
[analyzer] Simplify logic for ExprEngine::VisitUnaryExprOrTypeTraitExpr to avoid recursion to subexpression.
This exposed bugs in the live variables analysis, and a latent analyzer bug in the SymbolReaper.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137006 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/LiveVariables.cpp')
-rw-r--r-- | lib/Analysis/LiveVariables.cpp | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp index c6c091e129..71c1917c82 100644 --- a/lib/Analysis/LiveVariables.cpp +++ b/lib/Analysis/LiveVariables.cpp @@ -146,6 +146,19 @@ public: }; } +static const VariableArrayType *FindVA(QualType Ty) { + const Type *ty = Ty.getTypePtr(); + while (const ArrayType *VT = dyn_cast<ArrayType>(ty)) { + if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(VT)) + if (VAT->getSizeExpr()) + return VAT; + + ty = VT->getElementType().getTypePtr(); + } + + return 0; +} + void TransferFunctions::Visit(Stmt *S) { if (observer) observer->observeStmt(S, currentBlock, val); @@ -174,6 +187,17 @@ void TransferFunctions::Visit(Stmt *S) { CE->getImplicitObjectArgument()->IgnoreParens()); break; } + case Stmt::DeclStmtClass: { + const DeclStmt *DS = cast<DeclStmt>(S); + if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) { + for (const VariableArrayType* VA = FindVA(VD->getType()); + VA != 0; VA = FindVA(VA->getElementType())) { + val.liveStmts = LV.SSetFact.add(val.liveStmts, + VA->getSizeExpr()->IgnoreParens()); + } + } + break; + } // FIXME: These cases eventually shouldn't be needed. case Stmt::ExprWithCleanupsClass: { S = cast<ExprWithCleanups>(S)->getSubExpr(); @@ -187,6 +211,10 @@ void TransferFunctions::Visit(Stmt *S) { S = cast<MaterializeTemporaryExpr>(S)->GetTemporaryExpr(); break; } + case Stmt::UnaryExprOrTypeTraitExprClass: { + // No need to unconditionally visit subexpressions. + return; + } } for (Stmt::child_iterator it = S->child_begin(), ei = S->child_end(); @@ -281,16 +309,11 @@ VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) if (UE->getKind() != UETT_SizeOf || UE->isArgumentType()) return; - const DeclRefExpr *DR = - dyn_cast<DeclRefExpr>(UE->getArgumentExpr()->IgnoreParens()); - - if (!DR) - return; - - const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()); - - if (VD && VD->getType()->isVariableArrayType()) - val.liveDecls = LV.DSetFact.add(val.liveDecls, VD); + const Expr *subEx = UE->getArgumentExpr(); + if (subEx->getType()->isVariableArrayType()) { + assert(subEx->isLValue()); + val.liveStmts = LV.SSetFact.add(val.liveStmts, subEx->IgnoreParens()); + } } void TransferFunctions::VisitUnaryOperator(UnaryOperator *UO) { |