[clang] [Clang] Add captures to the instantiation scope for noexcept specifiers (PR #97166)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 29 06:46:24 PDT 2024
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/97166
The noexcept specifiers of dependent lambdas would be transformed and rebuilt, where the map of instantiation should also contain captured variables in case they are used from the noexcept specifier.
I also uncovered another assertion failure while at it. However, I decided to leave it as-is because 1) that doesn't appear to be the case in the release version and 2) fixing that might lead to ABI breakage. Anyhow, the case has been added to the test comment.
Fixes https://github.com/llvm/llvm-project/issues/95735
>From 91a28dcde9dc569b955df92db91c858c550f6ad3 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 29 Jun 2024 21:32:01 +0800
Subject: [PATCH] [Clang] Add captures to the instantiation scope for noexcept
specifiers
---
clang/docs/ReleaseNotes.rst | 1 +
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 6 +++++
clang/test/SemaTemplate/generic-lambda.cpp | 23 +++++++++++++++++++
3 files changed, 30 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index da967fcdda808..8c5bd989c60ce 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -935,6 +935,7 @@ Bug Fixes to C++ Support
- Fix an assertion failure caused by parsing a lambda used as a default argument for the value of a
forward-declared class. (#GH93512).
- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788).
+- Fixed a bug where references to lambda capture inside a ``noexcept`` specifier were not correctly instantiated. (#GH95735).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 0681520764d9a..d33db60d78448 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4719,6 +4719,12 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
return;
}
+ // The noexcept specification could reference any lambda captures. Ensure
+ // those are added to the LocalInstantiationScope.
+ LambdaScopeForCallOperatorInstantiationRAII PushLambdaCaptures(
+ *this, Decl, TemplateArgs, Scope,
+ /*ShouldAddDeclsFromParentScope=*/false);
+
SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(),
TemplateArgs);
}
diff --git a/clang/test/SemaTemplate/generic-lambda.cpp b/clang/test/SemaTemplate/generic-lambda.cpp
index fb5fa09ebcc1f..804eeaa29d6a1 100644
--- a/clang/test/SemaTemplate/generic-lambda.cpp
+++ b/clang/test/SemaTemplate/generic-lambda.cpp
@@ -60,3 +60,26 @@ template<class T1> C1<X<X<T1>>> auto t3() {
template C1<X<X<int>>> auto t3<int>();
static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>);
#endif
+
+namespace GH95735 {
+
+int g(int fn) {
+ return [f = fn](auto tpl) noexcept(noexcept(f)) { return f; }(0);
+}
+
+int foo(auto... fn) {
+ // FIXME: This one hits the assertion "if the exception specification is dependent,
+ // then the noexcept expression should be value-dependent" in the constructor of
+ // FunctionProtoType.
+ // One possible solution is to update Sema::canThrow() to consider expressions
+ // (e.g. DeclRefExpr/FunctionParmPackExpr) involving unexpanded parameters as Dependent.
+ // This would effectively add an extra value-dependent flag to the noexcept expression.
+ // However, I'm afraid that would also cause ABI breakage.
+ // [...f = fn](auto tpl) noexcept(noexcept(f)) { return 0; }(0);
+ [...f = fn](auto tpl) noexcept(noexcept(g(fn...))) { return 0; }(0);
+ return [...f = fn](auto tpl) noexcept(noexcept(g(f...))) { return 0; }(0);
+}
+
+int v = foo(42);
+
+} // namespace GH95735
More information about the cfe-commits
mailing list