[clang] [Clang] Add captures to the instantiation scope for noexcept specifiers (PR #97166)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 4 19:21:39 PDT 2024
https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/97166
>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 da967fcdda8089..8c5bd989c60cea 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 0681520764d9a0..d33db60d784487 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 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