[clang] e78a1f4 - [Clang] Fix the instantiation of return type requirements in lambda bodies (#76967)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 4 09:32:13 PST 2024
Author: 刘雨培
Date: 2024-01-05T01:32:10+08:00
New Revision: e78a1f491cbc0a57de7bf86058359dd0bd282540
URL: https://github.com/llvm/llvm-project/commit/e78a1f491cbc0a57de7bf86058359dd0bd282540
DIFF: https://github.com/llvm/llvm-project/commit/e78a1f491cbc0a57de7bf86058359dd0bd282540.diff
LOG: [Clang] Fix the instantiation of return type requirements in lambda bodies (#76967)
Currently, due to the incomplete implementation of p0588r1, the
instantiation of lambda expressions leads to the instantiation of the
body. And `EvaluateConstraints` is false during the instantiation of the
body, which causes crashes during the instantiation of the return type
requirement:
```cpp
template<typename T> concept doesnt_matter = true;
template<class T>
concept test =
[]{
return requires(T t) {
{ t } -> doesnt_matter; // crash
};
}();
static_assert(test<int>);
```
Although a complete implementation of p0588r1 can solve these crashes,
it will take some time. Therefore, this pull request aims to fix these
crashes first.
Fixes https://github.com/llvm/llvm-project/issues/63808
Fixes https://github.com/llvm/llvm-project/issues/64607
Fixes https://github.com/llvm/llvm-project/issues/64086
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/SemaTemplate/concepts-lambda.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c7bf162426a68c..e5de042cebd4c0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -844,6 +844,11 @@ Bug Fixes to C++ Support
- Fix crash when parsing nested requirement. Fixes:
(`#73112 <https://github.com/llvm/llvm-project/issues/73112>`_)
+- Fixed a crash caused by using return type requirement in a lambda. Fixes:
+ (`#63808 <https://github.com/llvm/llvm-project/issues/63808>`_)
+ (`#64607 <https://github.com/llvm/llvm-project/issues/64607>`_)
+ (`#64086 <https://github.com/llvm/llvm-project/issues/64086>`_)
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 37e5b9cad08bc9..e1cbdcd72eac1d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1479,6 +1479,23 @@ namespace {
return Result;
}
+ StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
+ // Currently, we instantiate the body when instantiating the lambda
+ // expression. However, `EvaluateConstraints` is disabled during the
+ // instantiation of the lambda expression, causing the instantiation
+ // failure of the return type requirement in the body. If p0588r1 is fully
+ // implemented, the body will be lazily instantiated, and this problem
+ // will not occur. Here, `EvaluateConstraints` is temporarily set to
+ // `true` to temporarily fix this issue.
+ // FIXME: This temporary fix can be removed after fully implementing
+ // p0588r1.
+ bool Prev = EvaluateConstraints;
+ EvaluateConstraints = true;
+ StmtResult Stmt = inherited::TransformLambdaBody(E, Body);
+ EvaluateConstraints = Prev;
+ return Stmt;
+ }
+
ExprResult TransformRequiresExpr(RequiresExpr *E) {
LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
ExprResult TransReq = inherited::TransformRequiresExpr(E);
diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp
index 8a184cbf4e9bc2..7e431529427dff 100644
--- a/clang/test/SemaTemplate/concepts-lambda.cpp
+++ b/clang/test/SemaTemplate/concepts-lambda.cpp
@@ -116,3 +116,36 @@ static_assert(E<int>);
// expected-note at -11{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
}
}
+
+namespace ReturnTypeRequirementInLambda {
+template <typename T>
+concept C1 = true;
+
+template <class T>
+concept test = [] {
+ return requires(T t) {
+ { t } -> C1;
+ };
+}();
+
+static_assert(test<int>);
+
+template <typename T>
+concept C2 = true;
+struct S1 {
+ int f1() { return 1; }
+};
+
+void foo() {
+ auto make_caller = []<auto member> {
+ return [](S1 *ps) {
+ if constexpr (requires {
+ { (ps->*member)() } -> C2;
+ })
+ ;
+ };
+ };
+
+ auto caller = make_caller.operator()<&S1::f1>();
+}
+} // namespace ReturnTypeRequirementInLambda
More information about the cfe-commits
mailing list