зеркало из https://github.com/microsoft/clang-1.git
Refine noreturn handling. Fixes -Wmissing-noreturn so that it doesn't
complain that functions that have a return statement should be declared noreturn. Fixed PR5286. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85195 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
848b9b6227
Коммит
1d7e767dc8
|
@ -988,7 +988,7 @@ public:
|
|||
void CheckCXXDefaultArguments(FunctionDecl *FD);
|
||||
void CheckExtraCXXDefaultArguments(Declarator &D);
|
||||
enum ControlFlowKind { NeverFallThrough = 0, MaybeFallThrough = 1,
|
||||
AlwaysFallThrough = 2 };
|
||||
AlwaysFallThrough = 2, NeverFallThroughOrReturn = 3 };
|
||||
ControlFlowKind CheckFallThrough(Stmt *);
|
||||
|
||||
Scope *getNonFieldDeclScope(Scope *S);
|
||||
|
|
|
@ -1044,6 +1044,7 @@ void Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
|
|||
/// Statement that should return a value.
|
||||
///
|
||||
/// \returns AlwaysFallThrough iff we always fall off the end of the statement,
|
||||
/// MaybeFallThroughOrReturn iff we might or might not fall off the end and
|
||||
/// MaybeFallThrough iff we might or might not fall off the end and
|
||||
/// NeverFallThrough iff we never fall off the end of the statement. We assume
|
||||
/// that functions not marked noreturn will return.
|
||||
|
@ -1054,7 +1055,8 @@ Sema::ControlFlowKind Sema::CheckFallThrough(Stmt *Root) {
|
|||
|
||||
// FIXME: They should never return 0, fix that, delete this code.
|
||||
if (cfg == 0)
|
||||
return NeverFallThrough;
|
||||
// FIXME: This should be NeverFallThrough
|
||||
return NeverFallThroughOrReturn;
|
||||
// The CFG leaves in dead things, and we don't want to dead code paths to
|
||||
// confuse us, so we mark all live things first.
|
||||
std::queue<CFGBlock*> workq;
|
||||
|
@ -1127,8 +1129,11 @@ Sema::ControlFlowKind Sema::CheckFallThrough(Stmt *Root) {
|
|||
if (NoReturnEdge == false)
|
||||
HasPlainEdge = true;
|
||||
}
|
||||
if (!HasPlainEdge)
|
||||
return NeverFallThrough;
|
||||
if (!HasPlainEdge) {
|
||||
if (HasLiveReturn)
|
||||
return NeverFallThrough;
|
||||
return NeverFallThroughOrReturn;
|
||||
}
|
||||
if (HasFakeEdge || HasLiveReturn)
|
||||
return MaybeFallThrough;
|
||||
// This says AlwaysFallThrough for calls to functions that are not marked
|
||||
|
@ -1192,10 +1197,12 @@ void Sema::CheckFallThroughForFunctionDef(Decl *D, Stmt *Body) {
|
|||
else if (!ReturnsVoid)
|
||||
Diag(Compound->getRBracLoc(), diag::warn_falloff_nonvoid_function);
|
||||
break;
|
||||
case NeverFallThrough:
|
||||
case NeverFallThroughOrReturn:
|
||||
if (ReturnsVoid && !HasNoReturn)
|
||||
Diag(Compound->getLBracLoc(), diag::warn_suggest_noreturn_function);
|
||||
break;
|
||||
case NeverFallThrough:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1243,10 +1250,12 @@ void Sema::CheckFallThroughForBlock(QualType BlockTy, Stmt *Body) {
|
|||
else if (!ReturnsVoid)
|
||||
Diag(Compound->getRBracLoc(), diag::err_falloff_nonvoid_block);
|
||||
break;
|
||||
case NeverFallThrough:
|
||||
case NeverFallThroughOrReturn:
|
||||
if (ReturnsVoid)
|
||||
Diag(Compound->getLBracLoc(), diag::warn_suggest_noreturn_block);
|
||||
break;
|
||||
case NeverFallThrough:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,22 @@
|
|||
// RUN: clang-cc %s -fsyntax-only -verify
|
||||
// RUN: clang-cc %s -fsyntax-only -verify -Wmissing-noreturn
|
||||
|
||||
int test1() {
|
||||
id a;
|
||||
@throw a;
|
||||
}
|
||||
|
||||
// PR5286
|
||||
void test2(int a) {
|
||||
while (1) {
|
||||
if (a)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// PR5286
|
||||
void test3(int a) { // expected-warning {{function could be attribute 'noreturn'}}
|
||||
while (1) {
|
||||
if (a)
|
||||
@throw (id)0;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче