From: Douglas Gregor Date: Fri, 10 Feb 2012 23:30:22 +0000 (+0000) Subject: Implement C++11 [expr.lambda.prim]p13, which prohibits lambdas in X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0459f87aaf05e76ce0d8c8c1e4c68e3c22195b7;p=clang Implement C++11 [expr.lambda.prim]p13, which prohibits lambdas in default arguments if in fact those lambdas capture any entity. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150282 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 0caf192fad..c35968cdb0 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4121,6 +4121,8 @@ def ext_lambda_implies_void_return : ExtWarn< InGroup>; def err_lambda_return_init_list : Error< "cannot deduce lambda return type from initializer list">; +def err_lambda_capture_default_arg : Error< + "lambda expression in default argument cannot capture any entity">; def err_operator_arrow_circular : Error< "circular pointer delegation detected">; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index ec92470ae1..a6d7d63b3a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -62,6 +62,7 @@ namespace { bool VisitExpr(Expr *Node); bool VisitDeclRefExpr(DeclRefExpr *DRE); bool VisitCXXThisExpr(CXXThisExpr *ThisE); + bool VisitLambdaExpr(LambdaExpr *Lambda); }; /// VisitExpr - Visit all of the children of this expression. @@ -111,6 +112,17 @@ namespace { diag::err_param_default_argument_references_this) << ThisE->getSourceRange(); } + + bool CheckDefaultArgumentVisitor::VisitLambdaExpr(LambdaExpr *Lambda) { + // C++11 [expr.lambda.prim]p13: + // A lambda-expression appearing in a default argument shall not + // implicitly or explicitly capture any entity. + if (Lambda->capture_begin() == Lambda->capture_end()) + return false; + + return S->Diag(Lambda->getLocStart(), + diag::err_lambda_capture_default_arg); + } } void Sema::ImplicitExceptionSpecification::CalledDecl(CXXMethodDecl *Method) { diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp new file mode 100644 index 0000000000..53f458a824 --- /dev/null +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 %s -Wunused -verify + +void f2() { + int i = 1; + void g1(int = ([i]{ return i; })()); // expected-error{{lambda expression in default argument cannot capture any entity}} + void g2(int = ([i]{ return 0; })()); // expected-error{{lambda expression in default argument cannot capture any entity}} + void g3(int = ([=]{ return i; })()); // expected-error{{lambda expression in default argument cannot capture any entity}} + void g4(int = ([=]{ return 0; })()); + void g5(int = ([]{ return sizeof i; })()); +}