-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[clang] reject to capture variable in RequiresExprBodyDecl
#78598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Congcong Cai (HerrCai0907) ChangesExpression in Full diff: https://github.com/llvm/llvm-project/pull/78598.diff 2 Files Affected:
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 6413a48f809ac9..767fc3787cb22f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19719,7 +19719,9 @@ bool Sema::tryCaptureVariable(
// we can bailout early.
if (CapturingFunctionScopes == 0 && (!BuildAndDiagnose || VarDC == DC))
return true;
-
+ // Expression in `RequiresExprBodyDecl` should not be captured.
+ if (isa<RequiresExprBodyDecl>(CurContext))
+ return true;
const auto *VD = dyn_cast<VarDecl>(Var);
if (VD) {
if (VD->isInitCapture())
diff --git a/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp b/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp
new file mode 100644
index 00000000000000..d01a54133f6c39
--- /dev/null
+++ b/clang/test/SemaCXX/requires-expression-with-capture-variable.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang -fsyntax-only -std=c++20 -Xclang -verify %s
+
+// expected-no-diagnostics
+
+auto GH69307_Func_1() {
+ constexpr auto b = 1;
+ return [&](auto c) -> int
+ requires requires { b + c; }
+ { return 1; };
+};
+auto GH69307_Func_Ret = GH69307_Func_1()(1);
+
+auto GH69307_Lambda_1 = []() {
+ return [&](auto c) -> int
+ requires requires { c; }
+ { return 1; };
+};
+auto GH69307_Lambda_1_Ret = GH69307_Lambda_1()(1);
+
+auto GH69307_Lambda_2 = [](auto c) {
+ return [&]() -> int
+ requires requires { c; }
+ { return 1; };
+};
+auto GH69307_Lambda_2_Ret = GH69307_Lambda_2(1)();
|
Thanks for the patch! Requires Expressions should be in an unevaluated context, so we should never try to capture variables they mentioned. Maybe we need to test the evaluation context in either https://eel.is/c++draft/expr.prim.lambda.capture#7.sentence-2 WDYT? |
I think this also fixes #63845 and the example in #41751 (comment), and even #67260! |
33db497
to
a99f16f
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
We will use |
…some-certain-requires-clauses-in-calculateconstraintsatisfaction
ping @erichkeane @cor3ntin |
You have an example of that? There may be further bugs there. |
I think it is from standard, but from user-friendly site. Now clang will hint user some variables is not need to capture in unevaluated context. The current implement is clang will try to capture it and then throw a diagnose and then give up to capture. auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; |
clang/lib/Sema/SemaExpr.cpp
Outdated
@@ -19706,22 +19706,29 @@ static void buildLambdaCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI, | |||
} | |||
} | |||
|
|||
static DeclContext *ignoreReuquiresBodyDecl(DeclContext *DC) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static DeclContext *ignoreReuquiresBodyDecl(DeclContext *DC) { | |
static DeclContext *ignoreRequiresBodyDecl(DeclContext *DC) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name here doesn't match what you're doing here. Perhaps something closer to getParentIgnoringRequiresBodyDecl
? Not a great name either, but better I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think inline it will be better since we only call it once.
|
||
auto GH69307_Func_1() { | ||
constexpr auto b = 1; | ||
return [&](auto c) -> int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do a similar test with NO capture here? To show that they aren't needed.
|
||
void test() { | ||
int i; | ||
auto explicit_by_value_unused_requires = [i] (auto) requires requires { i; } {}; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be PARTICULARLY good if we could 'remember' that it was 'used' in the requires clause so we can add a note that says something like (please consider wording and write better:)), note: use in requires expr doesn't use captures because they are special
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be interesting. I will try to do it later in festival.
This PR should also be able to fix #63972. |
Could you please explain why you're closing the PR? |
If @HerrCai0907 doesn't reply, we should take over |
I would open a new PR and reference this one in the summary for completeness. It looks like this one is not going to picked up by the author and so if you can take it over and finish it that would be very much appreciated. There are a lot of issues that crash similarly and so we likely have plenty of tests to try against a fix :-) |
This patch picks up llvm#78598 with the hope that we can address such crashes in tryCaptureVariable for unevaluated lambdas. In addition to tryCaptureVariable, this also contains several other fixes on e.g. lambda parsing/dependencies.
This patch picks up #78598 with the hope that we can address such crashes in `tryCaptureVariable()` for unevaluated lambdas. In addition to `tryCaptureVariable()`, this also contains several other fixes on e.g. lambda parsing/dependencies. Fixes #63845 Fixes #67260 Fixes #69307 Fixes #88081 Fixes #89496 Fixes #90669 Fixes #91633
RequiresExprBodyDecl
will be inCurContext
. Then is will cause mismatch betweenCurContext
andFunctionScopes
.This patch wants to ignore
RequiresExprBodyDecl
inCurContext
.Fixes: #69307, #76593.