Teach -Wreturn-type that destructors can appear

after a 'return' in a CFGBlock.  This accidentally
was working before, but the false assumption that
'return' always appeared at the end of the block
was uncovered by a recent change.

llvm-svn: 124280
This commit is contained in:
Ted Kremenek 2011-01-26 04:49:52 +00:00
parent e543be3531
commit 5d068499a7
2 changed files with 24 additions and 11 deletions

View File

@ -121,26 +121,29 @@ static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
const CFGBlock& B = **I;
if (!live[B.getBlockID()])
continue;
if (B.size() == 0) {
// Destructors can appear after the 'return' in the CFG. This is
// normal. We need to look pass the destructors for the return
// statement (if it exists).
CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
for ( ; ri != re ; ++ri) {
CFGElement CE = *ri;
if (isa<CFGStmt>(CE))
break;
}
// No more CFGElements in the block?
if (ri == re) {
if (B.getTerminator() && isa<CXXTryStmt>(B.getTerminator())) {
HasAbnormalEdge = true;
continue;
}
// A labeled empty statement, or the entry block...
HasPlainEdge = true;
continue;
}
CFGElement CE = B[B.size()-1];
if (!isa<CFGStmt>(CE)) {
HasPlainEdge = true;
continue;
}
CFGStmt CS = CE.getAs<CFGStmt>();
if (!CS.isValid())
continue;
CFGStmt CS = cast<CFGStmt>(*ri);
Stmt *S = CS.getStmt();
if (isa<ReturnStmt>(S)) {
HasLiveReturn = true;

View File

@ -93,3 +93,13 @@ int rdar8875247_test() {
rdar8875247 f;
} // expected-warning{{control reaches end of non-void function}}
struct rdar8875247_B {
rdar8875247_B();
~rdar8875247_B();
};
rdar8875247_B test_rdar8875247_B() {
rdar8875247_B f;
return f;
} // no-warning