[clang] f5f3d5d - [Clang][Sema] Fix a crash in lambda instantiation (#85565)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 19 17:33:34 PDT 2024


Author: Qizhi Hu
Date: 2024-03-20T08:33:30+08:00
New Revision: f5f3d5d6534f0a38c771119653dac3330c9f207f

URL: https://github.com/llvm/llvm-project/commit/f5f3d5d6534f0a38c771119653dac3330c9f207f
DIFF: https://github.com/llvm/llvm-project/commit/f5f3d5d6534f0a38c771119653dac3330c9f207f.diff

LOG: [Clang][Sema] Fix a crash in lambda instantiation (#85565)

Fix https://github.com/llvm/llvm-project/issues/85343
When build lambda expression in lambda instantiation, `ThisType` is
required in `Sema::CheckCXXThisCapture` to build `this` capture. Set
`this` type by import `Sema::CXXThisScopeRAII` and it will be used later
in lambda expression transformation.

Co-authored-by: huqizhi <836744285 at qq.com>

Added: 
    clang/test/Sema/PR85343.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/TreeTransform.h

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5ddad61e27c909..0ce3cbe3266efd 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 2d22692f3ab750..f2f7d7ab9c7c38 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 00000000000000..d90ef19d423455
--- /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; }


        


More information about the cfe-commits mailing list