Skip to content

Commit

Permalink
[Concepts] Traverse the instantiation chain for parameter injection i…
Browse files Browse the repository at this point in the history
…nside a constraint scope (llvm#79568)

We preserve the trailing requires-expression during the lambda
expression transformation. In order to get those referenced parameters
inside a requires-expression properly resolved to the instantiated
decls, we intended to inject these 'original' `ParmVarDecls` to the
current instantiaion scope, at `Sema::SetupConstraintScope`.

The previous approach seems to overlook nested instantiation chains,
leading to the crash within a nested lambda followed by a requires
clause.

This fixes llvm#73418.
  • Loading branch information
zyn0217 committed Jan 31, 2024
1 parent 400a02b commit 16a8c31
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,10 @@ Bug Fixes to C++ Support
Fixes (`#78830 <https://github.com/llvm/llvm-project/issues/78830>`_)
Fixes (`#60085 <https://github.com/llvm/llvm-project/issues/60085>`_)

- Fixed a bug where variables referenced by requires-clauses inside
nested generic lambdas were not properly injected into the constraint scope.
(`#73418 <https://github.com/llvm/llvm-project/issues/73418>`_)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,8 +612,12 @@ bool Sema::SetupConstraintScope(

// If this is a member function, make sure we get the parameters that
// reference the original primary template.
if (const auto *FromMemTempl =
PrimaryTemplate->getInstantiatedFromMemberTemplate()) {
// We walk up the instantiated template chain so that nested lambdas get
// handled properly.
for (FunctionTemplateDecl *FromMemTempl =
PrimaryTemplate->getInstantiatedFromMemberTemplate();
FromMemTempl;
FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
if (addInstantiatedParametersToScope(FD, FromMemTempl->getTemplatedDecl(),
Scope, MLTAL))
return true;
Expand Down
18 changes: 18 additions & 0 deletions clang/test/SemaTemplate/concepts-lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,21 @@ void foo() {
auto caller = make_caller.operator()<&S1::f1>();
}
} // namespace ReturnTypeRequirementInLambda

namespace GH73418 {
void foo() {
int x;
[&x](auto) {
return [](auto y) {
return [](auto obj, auto... params)
requires requires {
sizeof...(params);
[](auto... pack) {
return sizeof...(pack);
}(params...);
}
{ return false; }(y);
}(x);
}(x);
}
} // namespace GH73418

0 comments on commit 16a8c31

Please sign in to comment.