Skip to content

Commit 91a28dc

Browse files
committed
[Clang] Add captures to the instantiation scope for noexcept specifiers
1 parent 2a948d1 commit 91a28dc

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,7 @@ Bug Fixes to C++ Support
935935
- Fix an assertion failure caused by parsing a lambda used as a default argument for the value of a
936936
forward-declared class. (#GH93512).
937937
- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788).
938+
- Fixed a bug where references to lambda capture inside a ``noexcept`` specifier were not correctly instantiated. (#GH95735).
938939

939940
Bug Fixes to AST Handling
940941
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4719,6 +4719,12 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
47194719
return;
47204720
}
47214721

4722+
// The noexcept specification could reference any lambda captures. Ensure
4723+
// those are added to the LocalInstantiationScope.
4724+
LambdaScopeForCallOperatorInstantiationRAII PushLambdaCaptures(
4725+
*this, Decl, TemplateArgs, Scope,
4726+
/*ShouldAddDeclsFromParentScope=*/false);
4727+
47224728
SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(),
47234729
TemplateArgs);
47244730
}

clang/test/SemaTemplate/generic-lambda.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,26 @@ template<class T1> C1<X<X<T1>>> auto t3() {
6060
template C1<X<X<int>>> auto t3<int>();
6161
static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>);
6262
#endif
63+
64+
namespace GH95735 {
65+
66+
int g(int fn) {
67+
return [f = fn](auto tpl) noexcept(noexcept(f)) { return f; }(0);
68+
}
69+
70+
int foo(auto... fn) {
71+
// FIXME: This one hits the assertion "if the exception specification is dependent,
72+
// then the noexcept expression should be value-dependent" in the constructor of
73+
// FunctionProtoType.
74+
// One possible solution is to update Sema::canThrow() to consider expressions
75+
// (e.g. DeclRefExpr/FunctionParmPackExpr) involving unexpanded parameters as Dependent.
76+
// This would effectively add an extra value-dependent flag to the noexcept expression.
77+
// However, I'm afraid that would also cause ABI breakage.
78+
// [...f = fn](auto tpl) noexcept(noexcept(f)) { return 0; }(0);
79+
[...f = fn](auto tpl) noexcept(noexcept(g(fn...))) { return 0; }(0);
80+
return [...f = fn](auto tpl) noexcept(noexcept(g(f...))) { return 0; }(0);
81+
}
82+
83+
int v = foo(42);
84+
85+
} // namespace GH95735

0 commit comments

Comments
 (0)