r311224 - [c++2a] Implement P0409R2 - Allow lambda capture [=, this] (by hamzasood)
Faisal Vali via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 18 20:43:07 PDT 2017
Author: faisalv
Date: Fri Aug 18 20:43:07 2017
New Revision: 311224
URL: http://llvm.org/viewvc/llvm-project?rev=311224&view=rev
Log:
[c++2a] Implement P0409R2 - Allow lambda capture [=,this] (by hamzasood)
This patch, by hamzasood, implements P0409R2, and allows [=, this] pre-C++2a as an extension (with appropriate warnings) for consistency.
https://reviews.llvm.org/D36572
Thanks Hamza!
Added:
cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
cfe/trunk/test/FixIt/fixit-cxx0x.cpp
cfe/trunk/www/cxx_status.html
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=311224&r1=311223&r2=311224&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Aug 18 20:43:07 2017
@@ -168,6 +168,9 @@ def CXXPre14CompatPedantic : DiagGroup<"
def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">;
def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
[CXXPre1zCompat]>;
+def CXXPre2aCompat : DiagGroup<"c++98-c++11-c++14-c++17-compat">;
+def CXXPre2aCompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic",
+ [CXXPre2aCompat]>;
def CXX98CompatBindToTemporaryCopy :
DiagGroup<"c++98-compat-bind-to-temporary-copy">;
@@ -784,6 +787,10 @@ def CXX14 : DiagGroup<"c++14-extensions"
// earlier C++ versions.
def CXX17 : DiagGroup<"c++17-extensions">;
+// A warning group for warnings about using C++2a features as extensions in
+// earlier C++ versions.
+def CXX2a : DiagGroup<"c++2a-extensions">;
+
def : DiagGroup<"c++0x-extensions", [CXX11]>;
def : DiagGroup<"c++1y-extensions", [CXX14]>;
def : DiagGroup<"c++1z-extensions", [CXX17]>;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=311224&r1=311223&r2=311224&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Aug 18 20:43:07 2017
@@ -6470,8 +6470,6 @@ let CategoryName = "Lambda Issue" in {
"%0 can appear only once in a capture list">;
def err_reference_capture_with_reference_default : Error<
"'&' cannot precede a capture when the capture default is '&'">;
- def err_this_capture_with_copy_default : Error<
- "'this' cannot be explicitly captured when the capture default is '='">;
def err_copy_capture_with_copy_default : Error<
"'&' must precede a capture when the capture default is '='">;
def err_capture_does_not_name_variable : Error<
@@ -6544,6 +6542,14 @@ let CategoryName = "Lambda Issue" in {
InGroup<CXXPre1zCompat>, DefaultIgnore;
def ext_star_this_lambda_capture_cxx17 : ExtWarn<
"capture of '*this' by copy is a C++17 extension">, InGroup<CXX17>;
+
+ // C++2a [=, this] captures.
+ def warn_cxx17_compat_equals_this_lambda_capture : Warning<
+ "explicit capture of 'this' with a capture default of '=' is incompatible "
+ "with C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
+ def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
+ "explicit capture of 'this' with a capture default of '=' "
+ "is a C++2a extension">, InGroup<CXX2a>;
}
def err_return_in_captured_stmt : Error<
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=311224&r1=311223&r2=311224&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Aug 18 20:43:07 2017
@@ -948,17 +948,15 @@ void Sema::ActOnStartOfLambdaDefinition(
continue;
}
- // C++1z [expr.prim.lambda]p8:
- // If a lambda-capture includes a capture-default that is =, each
- // simple-capture of that lambda-capture shall be of the form "&
- // identifier" or "* this". [ Note: The form [&,this] is redundant but
- // accepted for compatibility with ISO C++14. --end note ]
- if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis) {
- Diag(C->Loc, diag::err_this_capture_with_copy_default)
- << FixItHint::CreateRemoval(
- SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
- continue;
- }
+ // C++2a [expr.prim.lambda]p8:
+ // If a lambda-capture includes a capture-default that is =,
+ // each simple-capture of that lambda-capture shall be of the form
+ // "&identifier", "this", or "* this". [ Note: The form [&,this] is
+ // redundant but accepted for compatibility with ISO C++14. --end note ]
+ if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis)
+ Diag(C->Loc, !getLangOpts().CPlusPlus2a
+ ? diag::ext_equals_this_lambda_capture_cxx2a
+ : diag::warn_cxx17_compat_equals_this_lambda_capture);
// C++11 [expr.prim.lambda]p12:
// If this is captured by a local lambda expression, its nearest
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp?rev=311224&r1=311223&r2=311224&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp Fri Aug 18 20:43:07 2017
@@ -8,7 +8,7 @@ class X0 {
(void)[this, this] () {}; // expected-error {{'this' can appear only once}}
(void)[=, foo] () {}; // expected-error {{'&' must precede a capture when}}
(void)[=, &foo] () {};
- (void)[=, this] () {}; // expected-error {{'this' cannot be explicitly captured}}
+ (void)[=, this] () {}; // expected-warning {{C++2a extension}}
(void)[&, foo] () {};
(void)[&, &foo] () {}; // expected-error {{'&' cannot precede a capture when}}
(void)[&, this] () {};
@@ -23,7 +23,7 @@ struct S2 {
void S2::f(int i) {
(void)[&, i]{ };
(void)[&, &i]{ }; // expected-error{{'&' cannot precede a capture when the capture default is '&'}}
- (void)[=, this]{ }; // expected-error{{'this' cannot be explicitly captured}}
+ (void)[=, this]{ }; // expected-warning{{C++2a extension}}
(void)[=]{ this->g(i); };
(void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[i(0), i(1)]{ }; // expected-error{{'i' can appear only once in a capture list}}
Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=311224&r1=311223&r2=311224&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Fri Aug 18 20:43:07 2017
@@ -54,7 +54,6 @@ struct S2 {
void S2::f(int i) {
(void)[&, &i, &i]{}; // expected-error 2{{'&' cannot precede a capture when the capture default is '&'}}
- (void)[=, this]{ this->g(5); }; // expected-error{{'this' cannot be explicitly captured}}
(void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[&, i, i]{ }; // expected-error{{'i' can appear only once in a capture list}}
(void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}}
Added: cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp?rev=311224&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp (added)
+++ cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp Fri Aug 18 20:43:07 2017
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+// expected-no-diagnostics
+
+// This test does two things.
+// Deleting the copy constructor ensures that an [=, this] capture doesn't copy the object.
+// Accessing a member variable from the lambda ensures that the capture actually works.
+class A {
+ A(const A &) = delete;
+ int i;
+
+ void func() {
+ auto L = [=, this]() -> int { return i; };
+ L();
+ }
+};
Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=311224&r1=311223&r2=311224&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Fri Aug 18 20:43:07 2017
@@ -777,13 +777,12 @@ code. This issue is expected to be recti
<h2 id="cxx20">C++2a implementation status</h2>
-<p>Clang does not yet support any of the proposed features of
-<!--<p>Clang has <b>experimental</b> support for some proposed features of-->
+<p>Clang has <b>experimental</b> support for some proposed features of
the C++ standard following C++17, provisionally named C++2a.
Note that support for these features may change or be removed without notice,
as the draft C++2a standard evolves.
-<!--<p>You can use Clang in C++2a mode with the <code>-std=c++2a</code> option.</p>-->
+<p>You can use Clang in C++2a mode with the <code>-std=c++2a</code> option.</p>
<details open>
<summary>List of features and minimum Clang version with support</summary>
@@ -808,7 +807,7 @@ as the draft C++2a standard evolves.
<tr>
<td>Allow <i>lambda-capture</i> <tt>[=, this]</tt></td>
<td><a href="http://wg21.link/p0409r2">P0409R2</a></td>
- <td class="none" align="center">No</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr>
<td><tt>__VA_OPT__</tt> for preprocessor comma elision</td>
More information about the cfe-commits
mailing list