Make noreturn functions alter the CFG.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76133 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Mike Stump 2009-07-17 01:04:31 +00:00
Родитель 808825cd08
Коммит cd7bf230a7
2 изменённых файлов: 47 добавлений и 5 удалений

Просмотреть файл

@ -478,6 +478,36 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) {
case Stmt::ParenExprClass:
return WalkAST(cast<ParenExpr>(Terminator)->getSubExpr(), AlwaysAddStmt);
case Stmt::CallExprClass: {
bool NoReturn = false;
CallExpr *C = cast<CallExpr>(Terminator);
Expr *CEE = C->getCallee()->IgnoreParenCasts();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
// FIXME: We can follow objective-c methods and C++ member functions...
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
if (FD->hasAttr<NoReturnAttr>())
NoReturn = true;
}
}
if (!NoReturn)
break;
if (Block) {
if (!FinishBlock(Block))
return 0;
}
// Create new block with no successor for the remaining pieces.
Block = createBlock(false);
Block->appendStmt(Terminator);
// Wire this to the exit block directly.
Block->addSuccessor(&cfg->getExit());
return WalkAST_VisitChildren(Terminator);
}
default:
break;
};
@ -1190,7 +1220,7 @@ CFGBlock* CFGBuilder::VisitBreakStmt(BreakStmt* B) {
return 0;
}
// Now create a new block that ends with the continue statement.
// Now create a new block that ends with the break statement.
Block = createBlock(false);
Block->setTerminator(B);

Просмотреть файл

@ -138,7 +138,8 @@ int f17() {
// <rdar://problem/6506065>
// The values of dead stores are only "consumed" in an enclosing expression
// what that value is actually used. In other words, don't say "Although the value stored to 'x' is used...".
// what that value is actually used. In other words, don't say "Although the
// value stored to 'x' is used...".
int f18() {
int x = 0; // no-warning
if (1)
@ -173,3 +174,14 @@ void f20(void) {
#pragma unused(x)
}
void halt() __attribute__((noreturn));
int f21() {
int x = 4;
++x; // expected-warning{{never read}}
if (1) {
halt();
(void)x;
}
return 1;
}