aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-15 16:20:15 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-15 16:20:15 +0000
commit793cd1c4cdfaafc52e2c2ad9dae959befe4bb166 (patch)
tree8b212fa72a8aa9c6fbad4227c2fe027046566dc9 /lib/Sema/AnalysisBasedWarnings.cpp
parent0bcc3d87223d7796946bfa6dd6174af900d8eba4 (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.cpp36
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);
}