From d86d39cc9e3f84be0012516f8623608e97133261 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 26 Sep 2008 22:58:57 +0000 Subject: [PATCH] Add CFG support for implicit-control flow for VLA size expressions within an SizeOfAlignOfTypeExpr. llvm-svn: 56706 --- clang/lib/AST/CFG.cpp | 35 ++++++++++++++++++++----------- clang/test/Analysis/dead-stores.c | 7 ++++++- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/clang/lib/AST/CFG.cpp b/clang/lib/AST/CFG.cpp index 41ae454d44c5..0313ada82c50 100644 --- a/clang/lib/AST/CFG.cpp +++ b/clang/lib/AST/CFG.cpp @@ -180,6 +180,18 @@ private: bool badCFG; }; + +static VariableArrayType* FindVA(Type* t) { + while (ArrayType* vt = dyn_cast(t)) { + if (VariableArrayType* vat = dyn_cast(vt)) + if (vat->getSizeExpr()) + return vat; + + t = vt->getElementType().getTypePtr(); + } + + return 0; +} /// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can /// represent an arbitrary statement. Examples include a single expression @@ -405,6 +417,17 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) { case Stmt::StmtExprClass: return WalkAST_VisitStmtExpr(cast(Terminator)); + case Stmt::SizeOfAlignOfTypeExprClass: { + SizeOfAlignOfTypeExpr* E = cast(Terminator); + + // VLA types have expressions that must be evaluated. + for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr()); + VA != 0; VA = FindVA(VA->getElementType().getTypePtr())) + addStmt(VA->getSizeExpr()); + + return Block; + } + case Stmt::UnaryOperatorClass: { UnaryOperator* U = cast(Terminator); @@ -475,18 +498,6 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) { if (AlwaysAddStmt) Block->appendStmt(Terminator); return WalkAST_VisitChildren(Terminator); } - -static VariableArrayType* FindVA(Type* t) { - while (ArrayType* vt = dyn_cast(t)) { - if (VariableArrayType* vat = dyn_cast(vt)) - if (vat->getSizeExpr()) - return vat; - - t = vt->getElementType().getTypePtr(); - } - - return 0; -} /// WalkAST_VisitDeclSubExpr - Utility method to add block-level expressions /// for initializers in Decls. diff --git a/clang/test/Analysis/dead-stores.c b/clang/test/Analysis/dead-stores.c index b1f16b9c844e..7335df511809 100644 --- a/clang/test/Analysis/dead-stores.c +++ b/clang/test/Analysis/dead-stores.c @@ -66,7 +66,6 @@ int f9() { return 1; } - int f10() { int x = 4; x = 10 + x; // expected-warning{{never read}} @@ -115,3 +114,9 @@ void f15(unsigned x, unsigned y) { int z[count]; } +int f16(int x) { + x = x * 2; + x = sizeof(int [x = (x || x + 1) * 2]); // expected-warning{{Although the value stored to 'x' is used}} + return x; +} +