Skip to content

Commit

Permalink
P0806R2 Implicit capture of this with a capture-default of [=] is
Browse files Browse the repository at this point in the history
deprecated.

Add a -Wdeprecated warning for this in C++2a onwards. (In C++17 and
before, there isn't a reasonable alternative because [=,this] is
ill-formed.)

llvm-svn: 336480
  • Loading branch information
zygoloid committed Jul 7, 2018
1 parent 9659a12 commit d82201e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -128,6 +129,7 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes,
DeprecatedDynamicExceptionSpec,
DeprecatedIncrementBool,
DeprecatedRegister,
DeprecatedThisCapture,
DeprecatedWritableStr]>,
DiagCategory<"Deprecations">;

Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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<
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Sema/SemaLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
12 changes: 10 additions & 2 deletions clang/test/SemaCXX/cxx2a-lambda-equals-this.cpp
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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}}
};
}
};

0 comments on commit d82201e

Please sign in to comment.