diff options
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Analysis/LiveVariables.cpp | 43 |
2 files changed, 42 insertions, 10 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index be6ffee668d..1edb328d013 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2204,6 +2204,15 @@ CFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E, 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; } 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) { |