[cfe-commits] r137006 - in /cfe/trunk/lib: Analysis/CFG.cpp Analysis/LiveVariables.cpp StaticAnalyzer/Core/ExprEngine.cpp
Ted Kremenek
kremenek at apple.com
Fri Aug 5 17:30:00 PDT 2011
Author: kremenek
Date: Fri Aug 5 19:30:00 2011
New Revision: 137006
URL: http://llvm.org/viewvc/llvm-project?rev=137006&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Analysis/LiveVariables.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=137006&r1=137005&r2=137006&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri Aug 5 19:30:00 2011
@@ -2204,6 +2204,15 @@
VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
lastBlock = addStmt(VA->getSizeExpr());
}
+ else {
+ // For sizeof(x), where 'x' is a VLA, we should include the computation
+ // of the lvalue of 'x'.
+ Expr *subEx = E->getArgumentExpr();
+ if (subEx->getType()->isVariableArrayType()) {
+ assert(subEx->isLValue());
+ lastBlock = addStmt(subEx);
+ }
+ }
return lastBlock;
}
Modified: cfe/trunk/lib/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/LiveVariables.cpp?rev=137006&r1=137005&r2=137006&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/lib/Analysis/LiveVariables.cpp Fri Aug 5 19:30:00 2011
@@ -146,6 +146,19 @@
};
}
+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 @@
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 @@
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 @@
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) {
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=137006&r1=137005&r2=137006&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Aug 5 19:30:00 2011
@@ -2269,25 +2269,20 @@
// Get the size by getting the extent of the sub-expression.
// First, visit the sub-expression to find its region.
const Expr *Arg = Ex->getArgumentExpr();
- ExplodedNodeSet Tmp;
- Visit(Arg, Pred, Tmp);
-
- for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
- const GRState* state = GetState(*I);
- const MemRegion *MR = state->getSVal(Arg).getAsRegion();
-
- // If the subexpression can't be resolved to a region, we don't know
- // anything about its size. Just leave the state as is and continue.
- if (!MR) {
- Dst.Add(*I);
- continue;
- }
+ const GRState *state = GetState(Pred);
+ const MemRegion *MR = state->getSVal(Arg).getAsRegion();
- // The result is the extent of the VLA.
- SVal Extent = cast<SubRegion>(MR)->getExtent(svalBuilder);
- MakeNode(Dst, Ex, *I, state->BindExpr(Ex, Extent));
+ // If the subexpression can't be resolved to a region, we don't know
+ // anything about its size. Just leave the state as is and continue.
+ if (!MR) {
+ Dst.Add(Pred);
+ return;
}
+ // The result is the extent of the VLA.
+ SVal Extent = cast<SubRegion>(MR)->getExtent(svalBuilder);
+ MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, Extent));
+
return;
}
else if (T->getAs<ObjCObjectType>()) {
More information about the cfe-commits
mailing list