[clang] Revert "[Clang] Instantiate local constexpr functions eagerly (#95660)" (PR #98991)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 16 03:52:39 PDT 2024
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 <zyn7109 at 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 <zyn7109 at 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
More information about the cfe-commits
mailing list