diff options
author | Mike Stump <mrs@apple.com> | 2009-07-28 22:04:01 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-07-28 22:04:01 +0000 |
commit | 3bf1ab48d30479a919fe1ebde9eceacda6d9b743 (patch) | |
tree | 72493ac74a26d723bef11a6427bb1152a1182222 /clang/lib/Sema/SemaDecl.cpp | |
parent | 26cf1e3baf7e565b7c7e69647cf961ad7a605ae2 (diff) | |
download | bcm5719-llvm-3bf1ab48d30479a919fe1ebde9eceacda6d9b743.tar.gz bcm5719-llvm-3bf1ab48d30479a919fe1ebde9eceacda6d9b743.zip |
Add noreturn support for blocks.
llvm-svn: 77377
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d3fe31e738e..7c0f849fd75 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1124,8 +1124,8 @@ Sema::ControlFlowKind Sema::CheckFallThrough(Stmt *Root) { /// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a /// function that should return a value. Check that we don't fall off the end -/// of a noreturn function. We assume that functions not marked noreturn will -/// return. +/// of a noreturn function. We assume that functions and blocks not marked +/// noreturn will return. void Sema::CheckFallThroughForFunctionDef(Decl *D, Stmt *Body) { // FIXME: Would be nice if we had a better way to control cascading errors, // but for now, avoid them. The problem is that when Parse sees: @@ -1175,6 +1175,51 @@ void Sema::CheckFallThroughForFunctionDef(Decl *D, Stmt *Body) { } } +/// CheckFallThroughForBlock - Check that we don't fall off the end of a block +/// that should return a value. Check that we don't fall off the end of a +/// noreturn block. We assume that functions and blocks not marked noreturn +/// will return. +void Sema::CheckFallThroughForBlock(QualType BlockTy, Stmt *Body) { + // FIXME: Would be nice if we had a better way to control cascading errors, + // but for now, avoid them. The problem is that when Parse sees: + // int foo() { return a; } + // The return is eaten and the Sema code sees just: + // int foo() { } + // which this code would then warn about. + if (getDiagnostics().hasErrorOccurred()) + return; + bool ReturnsVoid = false; + bool HasNoReturn = false; + if (const FunctionType *FT = BlockTy->getPointeeType()->getAsFunctionType()) { + if (FT->getResultType()->isVoidType()) + ReturnsVoid = true; + if (FT->getNoReturnAttr()) + HasNoReturn = true; + } + + if (ReturnsVoid && !HasNoReturn) + return; + // FIXME: Funtion try block + if (CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) { + switch (CheckFallThrough(Body)) { + case MaybeFallThrough: + if (HasNoReturn) + Diag(Compound->getRBracLoc(), diag::err_noreturn_block_has_return_expr); + else if (!ReturnsVoid) + Diag(Compound->getRBracLoc(), diag::err_maybe_falloff_nonvoid_block); + break; + case AlwaysFallThrough: + if (HasNoReturn) + Diag(Compound->getRBracLoc(), diag::err_noreturn_block_has_return_expr); + else if (!ReturnsVoid) + Diag(Compound->getRBracLoc(), diag::err_falloff_nonvoid_block); + break; + case NeverFallThrough: + break; + } + } +} + /// CheckParmsForFunctionDef - Check that the parameters of the given /// function are appropriate for the definition of a function. This /// takes care of any checks that cannot be performed on the |