aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/lib/Sema/TreeTransform.h10
-rw-r--r--clang/test/Sema/PR85343.cpp22
3 files changed, 33 insertions, 0 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5ddad61..0ce3cbe 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -401,6 +401,7 @@ Bug Fixes to C++ Support
expression references to an entity declared outside of the lambda. (#GH64808)
- Clang's __builtin_bit_cast will now produce a constant value for records with empty bases. See:
(#GH82383)
+- Fix a crash when instantiating a lambda that captures ``this`` outside of its context. Fixes (#GH85343).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 2d22692..f2f7d7a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -13714,6 +13714,16 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// Capturing 'this' is trivial.
if (C->capturesThis()) {
+ // If this is a lambda that is part of a default member initialiser
+ // and which we're instantiating outside the class that 'this' is
+ // supposed to refer to, adjust the type of 'this' accordingly.
+ //
+ // Otherwise, leave the type of 'this' as-is.
+ Sema::CXXThisScopeRAII ThisScope(
+ getSema(),
+ dyn_cast_if_present<CXXRecordDecl>(
+ getSema().getFunctionLevelDeclContext()),
+ Qualifiers());
getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
/*BuildAndDiagnose*/ true, nullptr,
C->getCaptureKind() == LCK_StarThis);
diff --git a/clang/test/Sema/PR85343.cpp b/clang/test/Sema/PR85343.cpp
new file mode 100644
index 0000000..d90ef19
--- /dev/null
+++ b/clang/test/Sema/PR85343.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++14 -verify %s
+// expected-no-diagnostics
+
+template <typename c> auto ab() -> c ;
+
+template <typename> struct e {};
+
+template <typename f> struct ac {
+ template <typename h> static e<decltype(ab<h>()(ab<int>))> i;
+ decltype(i<f>) j;
+};
+
+struct d {
+ template <typename f>
+ d(f) {
+ ac<f> a;
+ }
+};
+struct a {
+ d b = [=](auto) { (void)[this] {}; };
+};
+void b() { new a; }