[clang] f4c7811 - [Clang] Add captures to the instantiation scope for noexcept specifiers (#97166)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 6 18:46:42 PDT 2024
Author: Younan Zhang
Date: 2024-07-07T09:46:38+08:00
New Revision: f4c781174b4b8fd958d9074c25eb06b6e276cb1c
URL: https://github.com/llvm/llvm-project/commit/f4c781174b4b8fd958d9074c25eb06b6e276cb1c
DIFF: https://github.com/llvm/llvm-project/commit/f4c781174b4b8fd958d9074c25eb06b6e276cb1c.diff
LOG: [Clang] Add captures to the instantiation scope for noexcept specifiers (#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
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
clang/test/SemaTemplate/generic-lambda.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index edc932efd9416b..838cb69f647ee2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -973,6 +973,8 @@ Bug Fixes to C++ Support
of the address of operator. (#GH97483).
- Fixed an assertion failure about a constant expression which is a known integer but is not
evaluated to an integer. (#GH96670).
+- 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 64f6b01bed2292..2e90f0c215b8d9 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4704,6 +4704,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 fb5fa09ebcc1fd..804eeaa29d6a1d 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