[Clang] Ensure correct template parameter depth for abbreviated templates (#208699)
Fixes https://github.com/llvm/llvm-project/issues/200682
This commit is contained in:
1 parent
f114842d9e
commit
cfb25203c2
3 files changed
+45
-1
No files matched your search
@@ -838,6 +838,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
|
||||
|
||||
- Fixed a preprocessor assertion failure triggered when parsing an invalid template-id starting with `::template operator`. (#GH186582)
|
||||
- Fixed a crash when a function template is defined as a non-template friend with a global scope qualifier. (#GH185341)
|
||||
- Fixed a bug of incorrect template depth for abbreviated templates. (#GH200682)
|
||||
- Clang now rejects constant template parameters with block pointer types, since these are not implemented anyway and would lead to crashes. (#GH189247)
|
||||
- Fixed some concept bugs introduced in Clang 22 (#GH197597)
|
||||
- Clang no longer reject call expressions whose type is a not-yet-deduced auto type. (#GH207565)
|
||||
|
||||
@@ -2185,8 +2185,14 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
|
||||
while (MaybeParseHLSLAnnotations(D))
|
||||
;
|
||||
|
||||
if (Tok.is(tok::kw_requires))
|
||||
if (Tok.is(tok::kw_requires)) {
|
||||
TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
|
||||
// With abbreviated function templates - we need to explicitly add depth to
|
||||
// account for the implicit template parameter list induced by the template.
|
||||
if (!TemplateInfo.TemplateParams && D.getInventedTemplateParameterList())
|
||||
++CurTemplateDepthTracker;
|
||||
ParseTrailingRequiresClauseWithScope(D);
|
||||
}
|
||||
|
||||
// Save late-parsed attributes for now; they need to be parsed in the
|
||||
// appropriate function scope after the function Decl has been constructed.
|
||||
|
||||
@@ -361,6 +361,43 @@ struct foo {
|
||||
constexpr auto bar = foo(seq<0>());
|
||||
}
|
||||
|
||||
namespace GH200682 {
|
||||
|
||||
template <typename... Args> struct A {
|
||||
template <auto F> constexpr static bool B = F(42);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept c = true;
|
||||
|
||||
template <typename T>
|
||||
concept d = false;
|
||||
|
||||
void f(auto &&...args)
|
||||
requires(
|
||||
A<decltype(args)...>::template B<[](auto x) { return c<decltype(x)>; }>);
|
||||
|
||||
template <class>
|
||||
void g(auto &&...args)
|
||||
requires(
|
||||
A<decltype(args)...>::template B<[](auto x) { return c<decltype(x)>; }>);
|
||||
|
||||
void h(auto &&...args) // expected-note {{constraints not satisfied}}
|
||||
requires(
|
||||
A<decltype(args)...>::template B<[](auto x) { // expected-note {{evaluated to false}}
|
||||
return d<decltype(x)>;
|
||||
}>);
|
||||
|
||||
void main() {
|
||||
f();
|
||||
g<int>();
|
||||
|
||||
h(42);
|
||||
// expected-error@-1 {{no matching}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace GH147650 {
|
||||
template <int> int b;
|
||||
template <int b>
|
||||
|
||||
Reference in new issue
Block a user