aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-10 23:30:22 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-10 23:30:22 +0000
commitf0459f87aaf05e76ce0d8c8c1e4c68e3c22195b7 (patch)
tree7316b75e34f385e6f3290718f651137df4ea3613
parenta63b422eda86b9ff5a08395dcfc288a31419038e (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDeclCXX.cpp12
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp10
3 files changed, 24 insertions, 0 deletions
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<DiagGroup<"lambda-return">>;
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; })());
+}