summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td2
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--clang/lib/Sema/SemaLambda.cpp11
-rw-r--r--clang/test/SemaCXX/cxx2a-lambda-equals-this.cpp12
4 files changed, 28 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index a7fe5032dff..e021cf69758 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -120,6 +120,7 @@ def DeprecatedDynamicExceptionSpec
def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
def DeprecatedRegister : DiagGroup<"deprecated-register">;
+def DeprecatedThisCapture : DiagGroup<"deprecated-this-capture">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
// FIXME: Why is DeprecatedImplementations not in this group?
@@ -128,6 +129,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
DeprecatedDynamicExceptionSpec,
DeprecatedIncrementBool,
DeprecatedRegister,
+ DeprecatedThisCapture,
DeprecatedWritableStr]>,
DiagCategory<"Deprecations">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c02e7d27806..0f1ce0e1203 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6545,6 +6545,11 @@ let CategoryName = "Lambda Issue" in {
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 warn_deprecated_this_capture : Warning<
+ "implicit capture of 'this' with a capture default of '=' is deprecated">,
+ InGroup<DeprecatedThisCapture>, DefaultIgnore;
+ def note_deprecated_this_capture : Note<
+ "add an explicit capture of 'this' to capture '*this' by reference">;
}
def err_return_in_captured_stmt : Error<
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index fcacc2a17c9..5e69feceda6 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1548,6 +1548,17 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
// Handle 'this' capture.
if (From.isThisCapture()) {
+ // Capturing 'this' implicitly with a default of '[=]' is deprecated,
+ // because it results in a reference capture. Don't warn prior to
+ // C++2a; there's nothing that can be done about it before then.
+ if (getLangOpts().CPlusPlus2a && IsImplicit &&
+ CaptureDefault == LCD_ByCopy) {
+ Diag(From.getLocation(), diag::warn_deprecated_this_capture);
+ Diag(CaptureDefaultLoc, diag::note_deprecated_this_capture)
+ << FixItHint::CreateInsertion(
+ getLocForEndOfToken(CaptureDefaultLoc), ", this");
+ }
+
Captures.push_back(
LambdaCapture(From.getLocation(), IsImplicit,
From.isCopyCapture() ? LCK_StarThis : LCK_This));
diff --git a/clang/test/SemaCXX/cxx2a-lambda-equals-this.cpp b/clang/test/SemaCXX/cxx2a-lambda-equals-this.cpp
index ce6916322e5..652fb8da9b6 100644
--- a/clang/test/SemaCXX/cxx2a-lambda-equals-this.cpp
+++ b/clang/test/SemaCXX/cxx2a-lambda-equals-this.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -Wdeprecated
// This test does two things.
// Deleting the copy constructor ensures that an [=, this] capture doesn't copy the object.
@@ -13,3 +12,12 @@ class A {
L();
}
};
+
+struct B {
+ int i;
+ void f() {
+ (void) [=] { // expected-note {{add an explicit capture of 'this'}}
+ return i; // expected-warning {{implicit capture of 'this' with a capture default of '=' is deprecated}}
+ };
+ }
+};
OpenPOWER on IntegriCloud