Add CFG support for implicit-control flow for VLA size expressions within an SizeOfAlignOfTypeExpr.

llvm-svn: 56706
This commit is contained in:
Ted Kremenek 2008-09-26 22:58:57 +00:00
parent 597e70876e
commit d86d39cc9e
2 changed files with 29 additions and 13 deletions

View File

@ -181,6 +181,18 @@ private:
bool badCFG; 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 /// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can
/// represent an arbitrary statement. Examples include a single expression /// represent an arbitrary statement. Examples include a single expression
/// or a function body (compound statement). The ownership of the returned /// or a function body (compound statement). The ownership of the returned
@ -405,6 +417,17 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {
case Stmt::StmtExprClass: case Stmt::StmtExprClass:
return WalkAST_VisitStmtExpr(cast<StmtExpr>(Terminator)); 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: { case Stmt::UnaryOperatorClass: {
UnaryOperator* U = cast<UnaryOperator>(Terminator); UnaryOperator* U = cast<UnaryOperator>(Terminator);
@ -476,18 +499,6 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {
return WalkAST_VisitChildren(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 /// WalkAST_VisitDeclSubExpr - Utility method to add block-level expressions
/// for initializers in Decls. /// for initializers in Decls.
CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(ScopedDecl* D) { CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(ScopedDecl* D) {

View File

@ -66,7 +66,6 @@ int f9() {
return 1; return 1;
} }
int f10() { int f10() {
int x = 4; int x = 4;
x = 10 + x; // expected-warning{{never read}} x = 10 + x; // expected-warning{{never read}}
@ -115,3 +114,9 @@ void f15(unsigned x, unsigned y) {
int z[count]; 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;
}