forked from OSchip/llvm-project
Add CFG support for implicit-control flow for VLA size expressions within an SizeOfAlignOfTypeExpr.
llvm-svn: 56706
This commit is contained in:
parent
597e70876e
commit
d86d39cc9e
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue