[PATCH] D137172: [Clang] Implement CWG2358 Explicit capture of value
Corentin Jabot via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 1 09:38:30 PDT 2022
cor3ntin created this revision.
Herald added a project: All.
cor3ntin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D137172
Files:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/CXX/drs/dr23xx.cpp
clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
clang/www/cxx_dr_status.html
Index: clang/www/cxx_dr_status.html
===================================================================
--- clang/www/cxx_dr_status.html
+++ clang/www/cxx_dr_status.html
@@ -13956,7 +13956,7 @@
<td><a href="https://wg21.link/cwg2358">2358</a></td>
<td>CD5</td>
<td>Explicit capture of value</td>
- <td class="none" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 16</td>
</tr>
<tr id="2359">
<td><a href="https://wg21.link/cwg2359">2359</a></td>
Index: clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
===================================================================
--- clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.lambda/p13.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
+const int global = 0;
void f2() {
int i = 1;
void g1(int = ([i]{ return i; })()); // expected-error{{lambda expression in default argument cannot capture any entity}}
@@ -7,6 +8,8 @@
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; })());
+ void g6(int = ([x=1, y = global, &z = global]{ return x; })());
+ void g7(int = ([x=i, &y=i]{ return x; })()); // expected-error 2{{default argument references local variable 'i' of enclosing function}}
}
namespace lambda_in_default_args {
Index: clang/test/CXX/drs/dr23xx.cpp
===================================================================
--- clang/test/CXX/drs/dr23xx.cpp
+++ clang/test/CXX/drs/dr23xx.cpp
@@ -89,6 +89,16 @@
#pragma clang __debug dump not_use_2
}
+#if __cplusplus >= 201402L
+namespace dr2358 { // dr2358: 16
+ void f2() {
+ int i = 1;
+ void g1(int = ([x=1] { return x; }))(); // OK
+ void g2(int = ([x=i] { return x; }))(); // expected-error {{default argument references local variable 'i' of enclosing function}}
+ }
+}
+#endif
+
#if __cplusplus >= 201707L
// Otherwise, if the qualified-id std::tuple_size<E> names a complete class
// type **with a member value**, the expression std::tuple_size<E>::value shall
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -149,13 +149,19 @@
}
bool CheckDefaultArgumentVisitor::VisitLambdaExpr(const 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->getBeginLoc(), diag::err_lambda_capture_default_arg);
+ // [expr.prim.lambda.capture]/p9
+ // a lambda-expression appearing in a default argument cannot implicitly or explicitly capture any local entity.
+ // Such a lambda-expression can still have an init-capture if any full-expression in its initializer
+ // satisfies the constraints of an expression appearing in a default argument.
+ bool Invalid = false;
+ for(const LambdaCapture& LC : Lambda->captures()) {
+ if(!Lambda->isInitCapture(&LC))
+ return S.Diag(LC.getLocation(), diag::err_lambda_capture_default_arg);
+ // Init captures are always VarDecl.
+ auto *D = cast<VarDecl>(LC.getCapturedVar());
+ Invalid |= Visit(D->getInit());
+ }
+ return Invalid;
}
} // namespace
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -507,6 +507,7 @@
This means Clang will by default accept code using features from C++17 and
conforming GNU extensions. Projects incompatible with C++17 can add
``-std=gnu++14`` to their build settings to restore the previous behaviour.
+- Implemented DR2358 allowing init captures in lambdas in default arguments.
C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D137172.472334.patch
Type: text/x-patch
Size: 4065 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20221101/76d3b1c7/attachment-0001.bin>
More information about the cfe-commits
mailing list