Skip to content

Commit

Permalink
[Clang] Add captures to the instantiation scope for noexcept specifie…
Browse files Browse the repository at this point in the history
…rs (#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 #95735
  • Loading branch information
zyn0217 authored Jul 7, 2024
1 parent 1acb086 commit f4c7811
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
23 changes: 23 additions & 0 deletions clang/test/SemaTemplate/generic-lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit f4c7811

Please sign in to comment.