https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/98991
>From 727d92f0651cec3110d321582a884f1c939d8a6d Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Tue, 16 Jul 2024 12:43:33 +0800 Subject: [PATCH 1/2] Revert "[Clang] Instantiate local constexpr functions eagerly (#95660)" Unfortunately, this has caused a regression in DeduceReturnType(), which causes a problem in that some of the local recursive lambdas are incorrectly rejected. This reverts commit 5548ea34341e9d0ae645719c34b466ca3b9eaa5a. Also, this adds an offending case to the test. --- clang/docs/ReleaseNotes.rst | 1 - clang/lib/Sema/SemaExpr.cpp | 13 ++++---- .../SemaTemplate/instantiate-local-class.cpp | 33 +++++++++++-------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 838cb69f647ee..077063a828cbb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -960,7 +960,6 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). -- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849) - Fixed a failed assertion when attempting to convert an integer representing the difference between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (#GH95366). - Fix immediate escalation bugs in the presence of dependent call arguments. (#GH94935) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 852344d895ffd..9723de6f46fc7 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -17938,17 +17938,16 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, if (FirstInstantiation || TSK != TSK_ImplicitInstantiation || Func->isConstexpr()) { - if (Func->isConstexpr()) + if (isa<CXXRecordDecl>(Func->getDeclContext()) && + cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass() && + CodeSynthesisContexts.size()) + PendingLocalImplicitInstantiations.push_back( + std::make_pair(Func, PointOfInstantiation)); + else if (Func->isConstexpr()) // Do not defer instantiations of constexpr functions, to avoid the // expression evaluator needing to call back into Sema if it sees a // call to such a function. InstantiateFunctionDefinition(PointOfInstantiation, Func); - else if (isa<CXXRecordDecl>(Func->getDeclContext()) && - cast<CXXRecordDecl>(Func->getDeclContext()) - ->isLocalClass() && - CodeSynthesisContexts.size()) - PendingLocalImplicitInstantiations.push_back( - std::make_pair(Func, PointOfInstantiation)); else { Func->setInstantiationIsPending(true); PendingInstantiations.push_back( diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp index 7eee131e28d60..a313bdd9d2ea5 100644 --- a/clang/test/SemaTemplate/instantiate-local-class.cpp +++ b/clang/test/SemaTemplate/instantiate-local-class.cpp @@ -512,24 +512,31 @@ namespace LambdaInDefaultMemberInitializer { } #if __cplusplus >= 201703L -namespace GH35052 { -template <typename F> constexpr int func(F f) { - if constexpr (f(1UL)) { - return 1; +namespace local_recursive_lambda { + +template <typename F> struct recursive_lambda { + template <typename... Args> auto operator()(Args &&...args) const { + return fn(*this, args...); } - return 0; -} + F fn; +}; -int main() { - auto predicate = [](auto v) /*implicit constexpr*/ -> bool { - return v == 1; - }; +template <typename F> recursive_lambda(F) -> recursive_lambda<F>; + +struct Tree { + Tree *left, *right; +}; + +int sumSize(Tree *tree) { + auto accumulate = + recursive_lambda{[&](auto &self_fn, Tree *element_node) -> int { + return 1 + self_fn(tree->left) + self_fn(tree->right); + }}; - static_assert(predicate(1)); - return func(predicate); + return accumulate(tree); } -} // namespace GH35052 +} // namespace local_recursive_lambda #endif >From 44752766678a796b294c0cd8073a2e11c18988d8 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Tue, 16 Jul 2024 18:52:10 +0800 Subject: [PATCH 2/2] Add an issue reference --- .../SemaTemplate/instantiate-local-class.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp index a313bdd9d2ea5..298233739900f 100644 --- a/clang/test/SemaTemplate/instantiate-local-class.cpp +++ b/clang/test/SemaTemplate/instantiate-local-class.cpp @@ -513,6 +513,8 @@ namespace LambdaInDefaultMemberInitializer { #if __cplusplus >= 201703L +// Reduced from https://github.com/llvm/llvm-project/issues/98526 +// This relies on the deferral instantiation of the local lambda, otherwise we would fail in DeduceReturnType(). namespace local_recursive_lambda { template <typename F> struct recursive_lambda { @@ -524,17 +526,10 @@ template <typename F> struct recursive_lambda { template <typename F> recursive_lambda(F) -> recursive_lambda<F>; -struct Tree { - Tree *left, *right; -}; - -int sumSize(Tree *tree) { - auto accumulate = - recursive_lambda{[&](auto &self_fn, Tree *element_node) -> int { - return 1 + self_fn(tree->left) + self_fn(tree->right); - }}; - - return accumulate(tree); +void foo() { + recursive_lambda{[&](auto &self_fn, int) -> int { + return self_fn(0); + }}(0); } } // namespace local_recursive_lambda _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits