[cfe-commits] r150586 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/AnalysisBasedWarnings.cpp lib/Sema/SemaStmt.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 15 08:20:15 PST 2012
Author: dgregor
Date: Wed Feb 15 10:20:15 2012
New Revision: 150586
URL: http://llvm.org/viewvc/llvm-project?rev=150586&view=rev
Log:
Specialize noreturn diagnostics for lambda expressions.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=150586&r1=150585&r2=150586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Feb 15 10:20:15 2012
@@ -4045,6 +4045,14 @@
def ext_lambda_default_arguments : ExtWarn<
"C++11 forbids default arguments for lambda expressions">,
InGroup<LambdaExtensions>;
+ def err_noreturn_lambda_has_return_expr : Error<
+ "lambda declared 'noreturn' should not return">;
+ def warn_maybe_falloff_nonvoid_lambda : Warning<
+ "control may reach end of non-void lambda">,
+ InGroup<ReturnType>;
+ def warn_falloff_nonvoid_lambda : Warning<
+ "control reaches end of non-void lambda">,
+ InGroup<ReturnType>;
}
def err_operator_arrow_circular : Error<
Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=150586&r1=150585&r2=150586&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed Feb 15 10:20:15 2012
@@ -218,7 +218,8 @@
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 @@
else
D.diag_NeverFallThroughOrReturn = 0;
- D.funMode = true;
+ D.funMode = Function;
return D;
}
@@ -266,13 +267,28 @@
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 @@
== 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 @@
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);
}
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=150586&r1=150585&r2=150586&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed Feb 15 10:20:15 2012
@@ -1857,12 +1857,18 @@
QualType FnRetType = CurCap->ReturnType;
assert(!FnRetType.isNull());
- if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap))
+ if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
if (CurBlock->FunctionType->getAs<FunctionType>()->getNoReturnAttr()) {
Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
return StmtError();
}
- // FIXME: [[noreturn]] for lambdas!
+ } else {
+ LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CurCap);
+ if (LSI->CallOperator->getType()->getAs<FunctionType>()->getNoReturnAttr()){
+ Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr);
+ return StmtError();
+ }
+ }
// Otherwise, verify that this result type matches the previous one. We are
// pickier with blocks than for normal functions because we don't have GCC
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp?rev=150586&r1=150585&r2=150586&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp Wed Feb 15 10:20:15 2012
@@ -3,7 +3,9 @@
// An attribute-specifier-seq in a lambda-declarator appertains to the
// type of the corresponding function call operator.
void test_attributes() {
- auto nrl = []() [[noreturn]] {}; // expected-warning{{function declared 'noreturn' should not return}}
+ auto nrl = [](int x) -> int { if (x > 0) return x; }; // expected-warning{{control may reach end of non-void lambda}}
+
+ auto nrl2 = []() [[noreturn]] { return; }; // expected-error{{lambda declared 'noreturn' should not return}}
}
template<typename T>
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp?rev=150586&r1=150585&r2=150586&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp Wed Feb 15 10:20:15 2012
@@ -2,7 +2,7 @@
// Check that analysis-based warnings work in lambda bodies.
void analysis_based_warnings() {
- (void)[]() -> int { }; // expected-warning{{control reaches end of non-void function}}
+ (void)[]() -> int { }; // expected-warning{{control reaches end of non-void lambda}}
}
// Check that we get the right types of captured variables (the
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp?rev=150586&r1=150585&r2=150586&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp Wed Feb 15 10:20:15 2012
@@ -2,7 +2,7 @@
template<typename T>
void test_attributes() {
- auto nrl = []() [[noreturn]] {}; // expected-warning{{function declared 'noreturn' should not return}}
+ auto nrl = []() [[noreturn]] {}; // expected-error{{lambda declared 'noreturn' should not return}}
}
template void test_attributes<int>(); // expected-note{{in instantiation of function}}
More information about the cfe-commits
mailing list