https://github.com/yronglin updated 
https://github.com/llvm/llvm-project/pull/86960

>From a8a87484760874d3b36673970e7158f0247df69b Mon Sep 17 00:00:00 2001
From: yronglin <yronglin...@gmail.com>
Date: Thu, 26 Sep 2024 22:28:07 +0800
Subject: [PATCH] [clang][C++23] Extend lifetime of temporaries in
 mem-default-init for P2718R0

Signed-off-by: yronglin <yronglin...@gmail.com>
---
 clang/lib/Sema/SemaExpr.cpp                   |   2 +
 clang/lib/Sema/SemaInit.cpp                   |   2 +
 clang/test/CXX/special/class.temporary/p6.cpp | 106 +++++++++++++++++-
 clang/www/cxx_status.html                     |   9 +-
 4 files changed, 110 insertions(+), 9 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 66df9c969256a2..bde73670b0b07a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5639,6 +5639,8 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
       runWithSufficientStackSpace(Loc, [&] {
         MarkDeclarationsReferencedInExpr(E, /*SkipLocalVariables=*/false);
       });
+    if (isInLifetimeExtendingContext())
+      DiscardCleanupsInEvaluationContext();
     // C++11 [class.base.init]p7:
     //   The initialization of each base and member constitutes a
     //   full-expression.
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 4d11f2a43fcc6b..a5a716e7499f38 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -763,6 +763,8 @@ void InitListChecker::FillInEmptyInitForField(unsigned 
Init, FieldDecl *Field,
         SemaRef.currentEvaluationContext().DelayedDefaultInitializationContext 
=
             SemaRef.parentEvaluationContext()
                 .DelayedDefaultInitializationContext;
+        SemaRef.currentEvaluationContext().InLifetimeExtendingContext =
+            SemaRef.parentEvaluationContext().InLifetimeExtendingContext;
         DIE = SemaRef.BuildCXXDefaultInitExpr(Loc, Field);
       }
       if (DIE.isInvalid()) {
diff --git a/clang/test/CXX/special/class.temporary/p6.cpp 
b/clang/test/CXX/special/class.temporary/p6.cpp
index a6d2adfd1fd2c5..6c79de5dcbfae3 100644
--- a/clang/test/CXX/special/class.temporary/p6.cpp
+++ b/clang/test/CXX/special/class.temporary/p6.cpp
@@ -304,6 +304,26 @@ void check_dr1815() { // dr1815: yes
 }
 
 namespace P2718R0 {
+extern void block_scope_begin_function();
+extern void block_scope_end_function();
+
+template <typename E> using T2 = std::list<E>;
+template <typename E> const T2<E> &f1_temp(const T2<E> &t)  { return t; }
+template <typename E> const T2<E> &f2_temp(T2<E> t)         { return t; }
+template <typename E> T2<E> g_temp()                        { return T2<E>{}; }
+
+// -- Examples from https://wg21.link/p2718r0
+namespace std_examples {
+using T = std::list<int>;
+const T& f1(const T& t) { return t; }
+const T& f2(T t)        { return t; }
+T g();
+void foo() {
+  for (auto e : f1(g())) {}  // OK, lifetime of return value of g() extended
+  for (auto e : f2(g())) {}  // undefined behavior
+}
+} // namespace std_examples
+
 namespace basic {
 template <typename E> using T2 = std::list<E>;
 template <typename E> const T2<E> &f1_temp(const T2<E> &t)  { return t; }
@@ -463,6 +483,44 @@ template void default_arg_dependent_context2<int>();
 template void default_arg_dependent_context3<int>();
 } // namespace default_arg
 
+namespace default_init {
+template <class T>
+struct DepA {
+  T arr[1];
+  ~DepA() {}
+};
+
+template <class T>
+struct DepB {
+  int x;
+  const DepA<T> &a = DepA<T>{{0}};
+  ~DepB() {}
+  const int *begin() { return a.arr; }
+  const int *end() { return &a.arr[1]; }
+};
+
+template <typename T>
+void default_init1_dependent() {
+  // CHECK-CXX23: void 
@_ZN7P2718R012default_init23default_init1_dependentINS0_4DepBIiEEEEvv()
+  // CHECK-CXX23-LABEL: for.cond.cleanup:
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepBIiED1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepAIiED1Ev(
+  for (auto &&x : T{0}) {}
+}
+
+template <typename T>
+void default_init2_dependent() {
+  // CHECK-CXX23: void 
@_ZN7P2718R012default_init23default_init2_dependentINS0_4DepBIiEEEEvv()
+  // CHECK-CXX23-LABEL: for.cond.cleanup:
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepBIiED1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init4DepAIiED1Ev(
+  for (auto &&x : T{0}.a.arr) {}
+}
+
+template void default_init1_dependent<DepB<int>>();
+template void default_init2_dependent<DepB<int>>();
+} // namespace default_init
+
 namespace basic {
 using T = std::list<int>;
 const T& f1(const T& t) { return t; }
@@ -579,5 +637,51 @@ void default_arg3() {
   for (auto e : C(0, C(0, C(0, C())))) {}
 }
 } // namespace default_arg
-} // namespace P2718R0
 
+namespace default_init {
+struct X {
+  int x;
+  ~X() {}
+};
+
+struct Y {
+  int y;
+  const X &x = X{1};
+  ~Y() {}
+};
+
+struct A {
+  int arr[1];
+  const Y &y = Y{1};
+  ~A() {}
+};
+
+struct B {
+  int x;
+  const A &a = A{{0}};
+  ~B() {}
+  const int *begin() { return a.arr; }
+  const int *end() { return &a.arr[1]; }
+};
+
+void default_init1() {
+  // CHECK-CXX23: void @_ZN7P2718R012default_init13default_init1Ev()
+  // CHECK-CXX23-LABEL: for.cond.cleanup:
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1BD1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1AD1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1YD1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1XD1Ev(
+  for (auto &&x : B{0}) {}
+}
+
+void default_init2() {
+  // CHECK-CXX23: void @_ZN7P2718R012default_init13default_init2Ev()
+  // CHECK-CXX23-LABEL: for.cond.cleanup:
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1BD1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1AD1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1YD1Ev(
+  // CHECK-CXX23-NEXT: call void @_ZN7P2718R012default_init1XD1Ev(
+  for (auto &&x : B{0}.a.arr) {}
+}
+} // namespace default_init
+} // namespace P2718R0
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 3f6a46c08c8514..d59cbbbbec1b5b 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -475,14 +475,7 @@ <h2 id="cxx23">C++23 implementation status</h2>
     <tr>
       <td>Lifetime extension in range-based for loops</td>
       <td><a href="https://wg21.link/P2718R0";>P2718R0</a></td>
-      <td class="partial" align="center">
-        <details>
-          <summary>Clang 19 (Partial)</summary>
-            The lifetime extension of temporaries bound to member references
-            by default member initializers in aggregate initialization was
-            not supported now.
-        </details>
-      </td>
+      <td class="full" align="center">Clang 20</td>
     </tr>
     <!--Issaquah 2023 papers-->
     <tr>

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to