-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
[Clang] Diagnose unexpanded packs for NTTP type constraints #121296
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) ChangesOtherwise, the invalid unexpanded type would be passed to getAutoType and lead to a crash. Fixes #88866 Full diff: https://github.com/llvm/llvm-project/pull/121296.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 983c1da20ed4c8..db40a722ce1ed8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -886,6 +886,7 @@ Bug Fixes to C++ Support
out of a module (which is the case e.g. in MSVC's implementation of ``std`` module). (#GH118218)
- Fixed a pack expansion issue in checking unexpanded parameter sizes. (#GH17042)
- Fixed a bug where captured structured bindings were modifiable inside non-mutable lambda (#GH95081)
+- Clang now identifies unexpanded parameter packs within the type constraint on a non-type template parameter. (#GH88866)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5e7a3c8484c88f..eac184d468ce9a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1530,9 +1530,17 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
Param->setAccess(AS_public);
if (AutoTypeLoc TL = TInfo->getTypeLoc().getContainedAutoTypeLoc())
- if (TL.isConstrained())
- if (AttachTypeConstraint(TL, Param, Param, D.getEllipsisLoc()))
+ if (TL.isConstrained()) {
+ if (const ASTTemplateArgumentListInfo *ArgumentList =
+ TL.getConceptReference()->getTemplateArgsAsWritten())
+ for (const TemplateArgumentLoc &Loc : ArgumentList->arguments()) {
+ Invalid |= DiagnoseUnexpandedParameterPack(
+ Loc, UnexpandedParameterPackContext::UPPC_TypeConstraint);
+ }
+ if (!Invalid &&
+ AttachTypeConstraint(TL, Param, Param, D.getEllipsisLoc()))
Invalid = true;
+ }
if (Invalid)
Param->setInvalidDecl();
diff --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
index 0674135aac483f..509922c0a8f4fe 100644
--- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
+++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
@@ -305,3 +305,45 @@ static_assert(__is_same_as(_Three_way_comparison_result_with_tuple_like<tuple<in
static_assert(__is_same_as(_Three_way_comparison_result_with_tuple_like<tuple<int>, 0>::type, long));
}
+
+namespace GH88866 {
+
+template <typename...Ts> struct index_by;
+
+template <typename T, typename Indices>
+concept InitFunc = true;
+
+namespace Invalid {
+
+template <typename Indices, InitFunc<Indices> auto... init>
+struct LazyLitMatrix;
+
+template <
+ typename...Indices,
+ InitFunc<index_by<Indices>> auto... init
+ // expected-error@-1 {{type constraint contains unexpanded parameter pack 'Indices'}}
+>
+struct LazyLitMatrix<index_by<Indices...>, init...> {
+};
+
+using T = LazyLitMatrix<index_by<int, char>, 42, 43>;
+
+}
+
+namespace Valid {
+
+template <typename Indices, InitFunc<Indices> auto... init>
+struct LazyLitMatrix;
+
+template <
+ typename...Indices,
+ InitFunc<index_by<Indices...>> auto... init
+>
+struct LazyLitMatrix<index_by<Indices...>, init...> {
+};
+
+using T = LazyLitMatrix<index_by<int, char>, 42, 43>;
+
+}
+
+}
|
if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType())) | ||
if (auto *Expansion = dyn_cast<PackExpansionType>( | ||
S.Context.getUnconstrainedType(NTTP->getType()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cor3ntin I assume we are unable to deduce template arguments in the type constraint, right? This logic would otherwise end up matching the NTTP argument against the NTTP constraint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear. @zygoloid asked that exact question last year (https://lists.isocpp.org/core/2023/03/14099.php) but there are no replies yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sigh. Looks like having run into another dark corner of C++ :/
Otherwise, the invalid unexpanded type would be passed to getAutoType and lead to a crash.
Fixes #88866