diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-15 16:20:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-15 16:20:15 +0000 |
commit | 793cd1c4cdfaafc52e2c2ad9dae959befe4bb166 (patch) | |
tree | 8b212fa72a8aa9c6fbad4227c2fe027046566dc9 /lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 0bcc3d87223d7796946bfa6dd6174af900d8eba4 (diff) |
Specialize noreturn diagnostics for lambda expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 71bf3359ea..2d609001d4 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -218,7 +218,8 @@ struct CheckFallThroughDiagnostics { unsigned diag_AlwaysFallThrough_HasNoReturn; unsigned diag_AlwaysFallThrough_ReturnsNonVoid; unsigned diag_NeverFallThroughOrReturn; - bool funMode; + enum { Function, Block, Lambda } funMode; + bool IsLambda; SourceLocation FuncLoc; static CheckFallThroughDiagnostics MakeForFunction(const Decl *Func) { @@ -250,7 +251,7 @@ struct CheckFallThroughDiagnostics { else D.diag_NeverFallThroughOrReturn = 0; - D.funMode = true; + D.funMode = Function; return D; } @@ -266,13 +267,28 @@ struct CheckFallThroughDiagnostics { diag::err_falloff_nonvoid_block; D.diag_NeverFallThroughOrReturn = diag::warn_suggest_noreturn_block; - D.funMode = false; + D.funMode = Block; + return D; + } + + static CheckFallThroughDiagnostics MakeForLambda() { + CheckFallThroughDiagnostics D; + D.diag_MaybeFallThrough_HasNoReturn = + diag::err_noreturn_lambda_has_return_expr; + D.diag_MaybeFallThrough_ReturnsNonVoid = + diag::warn_maybe_falloff_nonvoid_lambda; + D.diag_AlwaysFallThrough_HasNoReturn = + diag::err_noreturn_lambda_has_return_expr; + D.diag_AlwaysFallThrough_ReturnsNonVoid = + diag::warn_falloff_nonvoid_lambda; + D.diag_NeverFallThroughOrReturn = 0; + D.funMode = Lambda; return D; } bool checkDiagnostics(DiagnosticsEngine &D, bool ReturnsVoid, bool HasNoReturn) const { - if (funMode) { + if (funMode == Function) { return (ReturnsVoid || D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function, FuncLoc) == DiagnosticsEngine::Ignored) @@ -284,9 +300,9 @@ struct CheckFallThroughDiagnostics { == DiagnosticsEngine::Ignored); } - // For blocks. - return ReturnsVoid && !HasNoReturn - && (!ReturnsVoid || + // For blocks / lambdas. + return ReturnsVoid && !HasNoReturn + && ((funMode == Lambda) || D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc) == DiagnosticsEngine::Ignored); } @@ -888,7 +904,11 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, if (P.enableCheckFallThrough) { const CheckFallThroughDiagnostics &CD = (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock() - : CheckFallThroughDiagnostics::MakeForFunction(D)); + : (isa<CXXMethodDecl>(D) && + cast<CXXMethodDecl>(D)->getOverloadedOperator() == OO_Call && + cast<CXXMethodDecl>(D)->getParent()->isLambda()) + ? CheckFallThroughDiagnostics::MakeForLambda() + : CheckFallThroughDiagnostics::MakeForFunction(D)); CheckFallThroughForBody(S, D, Body, blkExpr, CD, AC); } |