summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/LiveVariables.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-08-06 00:30:00 +0000
committerTed Kremenek <kremenek@apple.com>2011-08-06 00:30:00 +0000
commit84a1ca52807a4fd79dd1b43aa3700514638b0c65 (patch)
tree645e550f65d86d284dc1b6208429596c8fba4cd6 /clang/lib/Analysis/LiveVariables.cpp
parentc91ca30b4ce749ab3580bca9b10f463737932c46 (diff)
downloadbcm5719-llvm-84a1ca52807a4fd79dd1b43aa3700514638b0c65.tar.gz
bcm5719-llvm-84a1ca52807a4fd79dd1b43aa3700514638b0c65.zip
[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. llvm-svn: 137006
Diffstat (limited to 'clang/lib/Analysis/LiveVariables.cpp')
-rw-r--r--clang/lib/Analysis/LiveVariables.cpp43
1 files changed, 33 insertions, 10 deletions
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp
index c6c091e1295..71c1917c82f 100644
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ b/clang/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) {
OpenPOWER on IntegriCloud