https://github.com/yronglin updated https://github.com/llvm/llvm-project/pull/177191
>From e86733dcf62c01fefeae8048db0b13dbb8b88eef Mon Sep 17 00:00:00 2001 From: "Wang, Yihan" <[email protected]> Date: Thu, 22 Jan 2026 00:02:04 +0800 Subject: [PATCH 1/2] [clang] Fix lifetime extension of temporaries in for-range-initializers in templates Signed-off-by: Wang, Yihan <[email protected]> --- clang/lib/Sema/SemaStmt.cpp | 15 ++++---- clang/test/CXX/special/class.temporary/p6.cpp | 34 +++++++++++++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 1b1643250d05e..5ab10fdfc7b74 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2753,14 +2753,6 @@ StmtResult Sema::BuildCXXForRangeStmt( diag::err_for_range_incomplete_type)) return StmtError(); - // P2718R0 - Lifetime extension in range-based for loops. - if (getLangOpts().CPlusPlus23 && !LifetimeExtendTemps.empty()) { - InitializedEntity Entity = - InitializedEntity::InitializeVariable(RangeVar); - for (auto *MTE : LifetimeExtendTemps) - MTE->setExtendingDecl(RangeVar, Entity.allocateManglingNumber()); - } - // Build auto __begin = begin-expr, __end = end-expr. // Divide by 2, since the variables are in the inner scope (loop body). const auto DepthStr = std::to_string(S->getDepth() / 2); @@ -3017,6 +3009,13 @@ StmtResult Sema::BuildCXXForRangeStmt( if (getLangOpts().OpenMP >= 50 && BeginDeclStmt.isUsable()) OpenMP().ActOnOpenMPLoopInitialization(ForLoc, BeginDeclStmt.get()); + // P2718R0 - Lifetime extension in range-based for loops. + if (getLangOpts().CPlusPlus23 && !LifetimeExtendTemps.empty()) { + InitializedEntity Entity = InitializedEntity::InitializeVariable(RangeVar); + for (auto *MTE : LifetimeExtendTemps) + MTE->setExtendingDecl(RangeVar, Entity.allocateManglingNumber()); + } + return new (Context) CXXForRangeStmt( InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()), cast_or_null<DeclStmt>(EndDeclStmt.get()), NotEqExpr.get(), diff --git a/clang/test/CXX/special/class.temporary/p6.cpp b/clang/test/CXX/special/class.temporary/p6.cpp index 2b1b531b7172c..12e760b60e65b 100644 --- a/clang/test/CXX/special/class.temporary/p6.cpp +++ b/clang/test/CXX/special/class.temporary/p6.cpp @@ -700,4 +700,38 @@ void default_init2() { for (auto &&x : B{0}.a.arr) {} } } // namespace default_init + +namespace GH165182 { +extern "C" int printf(const char *, ...); + +const char* s = "1"; + +struct Foo { + int& x; + Foo(int& x) noexcept : x{x} {} + ~Foo() noexcept { x = 42; } + const char* begin() const noexcept { return s; } + const char* end() const noexcept { return s + 1; } +}; + +const Foo& f1(const Foo& t) noexcept { return t; } +Foo g(int& x) noexcept { return Foo(x); } + +// Lifetime extension is missing! +template <typename T> +int test1() { + int x = 5; + int sum = 0; + // CHECK-CXX23: for.cond.cleanup: + // CHECK-CXX23-NEXT: call void @_ZN7P2718R08GH1651823FooD1Ev( + for (int _ : f1(g(x))) sum += x; + sum += x; + return sum; +} + +int foo() { + printf("%i\n", test1<int>()); +} + +} // namespace GH165182 } // namespace P2718R0 >From 6249dfbf09c1c7b4482e9e430e3f8e481e261d66 Mon Sep 17 00:00:00 2001 From: "Wang, Yihan" <[email protected]> Date: Thu, 22 Jan 2026 00:18:15 +0800 Subject: [PATCH 2/2] Add release notes Signed-off-by: Wang, Yihan <[email protected]> --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5fd607d98faa3..6579a71563a57 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -134,6 +134,8 @@ Improvements to Coverage Mapping Bug Fixes in This Version ------------------------- +- Fix lifetime extension of temporaries in for-range-initializers in templates. (#GH165182) + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
