aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-09-26 22:58:57 +0000
committerTed Kremenek <kremenek@apple.com>2008-09-26 22:58:57 +0000
commit610a09e409bea151a42dd907768f1e0c4b103f1f (patch)
treedd9366b3d348fbcbba99d4b527f92f51d4817c89
parenta2c6912c416c2d9f79d18f3a88ab0ae2609286c3 (diff)
Add CFG support for implicit-control flow for VLA size expressions within an SizeOfAlignOfTypeExpr.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56706 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/CFG.cpp35
-rw-r--r--test/Analysis/dead-stores.c7
2 files changed, 29 insertions, 13 deletions
diff --git a/lib/AST/CFG.cpp b/lib/AST/CFG.cpp
index 41ae454d44..0313ada82c 100644
--- a/lib/AST/CFG.cpp
+++ b/lib/AST/CFG.cpp
@@ -180,6 +180,18 @@ private:
bool badCFG;
};
+
+static VariableArrayType* FindVA(Type* t) {
+ while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
+ if (VariableArrayType* vat = dyn_cast<VariableArrayType>(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<StmtExpr>(Terminator));
+ case Stmt::SizeOfAlignOfTypeExprClass: {
+ SizeOfAlignOfTypeExpr* E = cast<SizeOfAlignOfTypeExpr>(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<UnaryOperator>(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<ArrayType>(t)) {
- if (VariableArrayType* vat = dyn_cast<VariableArrayType>(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/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index b1f16b9c84..7335df5118 100644
--- a/test/Analysis/dead-stores.c
+++ b/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;
+}
+