Skip to content

[Clang] fix generic lambda inside requires-clause of friend function template #99813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ Bug Fixes to C++ Support
- Clang now properly handles the order of attributes in `extern` blocks. (#GH101990).
- Fixed an assertion failure by preventing null explicit object arguments from being deduced. (#GH102025).
- Correctly check constraints of explicit instantiations of member functions. (#GH46029)
- Fixed an assertion failure about a constraint of a friend function template references to a value with greater
template depth than the friend function template. (#GH98258)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
10 changes: 2 additions & 8 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1667,10 +1667,7 @@ class ConstraintRefersToContainingTemplateChecker
}

void CheckNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
assert(D->getDepth() <= TemplateDepth &&
"Nothing should reference a value below the actual template depth, "
"depth is likely wrong");
if (D->getDepth() != TemplateDepth)
if (D->getDepth() < TemplateDepth)
Result = true;

// Necessary because the type of the NTTP might be what refers to the parent
Expand All @@ -1694,10 +1691,7 @@ class ConstraintRefersToContainingTemplateChecker
using inherited::TransformTemplateTypeParmType;
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
TemplateTypeParmTypeLoc TL, bool) {
assert(TL.getDecl()->getDepth() <= TemplateDepth &&
"Nothing should reference a value below the actual template depth, "
"depth is likely wrong");
if (TL.getDecl()->getDepth() != TemplateDepth)
if (TL.getDecl()->getDepth() < TemplateDepth)
Comment on lines -1697 to +1694
Copy link
Contributor

@zyn0217 zyn0217 Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the justification for removing the assert here. When would we otherwise hit it?

Besides, we have the same pattern in CheckNonTypeTemplateParmDecl() above. Does it also impact anything?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Oh, I saw the issue, just disregard my first question.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not notice that before, and we do have similar issue when it comes to NTTP godbolt

Result = true;
return inherited::TransformTemplateTypeParmType(
TLB, TL,
Expand Down
21 changes: 21 additions & 0 deletions clang/test/SemaTemplate/concepts-friends.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,24 @@ template struct Z<int>;
Y y(1);

}

namespace GH98258 {

struct S {
template <typename U>
friend void f() requires requires { []<typename V>(V){}; } {
return;
}

template <typename U>
friend void f2() requires requires { [](auto){}; } {
return;
}

template <typename U>
friend void f3() requires requires { []<int X>(){ return X; }; } {
return;
}
};

}
Loading