[clang] 979eb55 - [Clang][Sema] Differentiate between partial/explicit specializations when diagnosing unexpanded packs (#72015)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 16 01:46:49 PST 2023
Author: Krystian Stasiowski
Date: 2023-11-16T10:46:44+01:00
New Revision: 979eb558dd7c203be10fa24ab2b0d7cb93c3443b
URL: https://github.com/llvm/llvm-project/commit/979eb558dd7c203be10fa24ab2b0d7cb93c3443b
DIFF: https://github.com/llvm/llvm-project/commit/979eb558dd7c203be10fa24ab2b0d7cb93c3443b.diff
LOG: [Clang][Sema] Differentiate between partial/explicit specializations when diagnosing unexpanded packs (#72015)
This adds `UnexpandedParameterPackContext::UPPC_ExplicitSpecialization`
and passes it to `DiagnoseUnexpandedParameterPack` when checking
class/variable template explicit specializations.
Right now we don't check for unexpanded packs in function template
explicit specializations at all, so I will be addressing that in a
followup PR.
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaTemplate.cpp
clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f9dec60cf990784..a9dde041bc22a6d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5655,9 +5655,9 @@ def err_unexpanded_parameter_pack : Error<
"%select{expression|base type|declaration type|data member type|bit-field "
"size|static assertion|fixed underlying type|enumerator value|"
"using declaration|friend declaration|qualifier|initializer|default argument|"
- "non-type template parameter type|exception type|partial specialization|"
- "__if_exists name|__if_not_exists name|lambda|block|type constraint|"
- "requirement|requires clause}0 "
+ "non-type template parameter type|exception type|explicit specialization|"
+ "partial specialization|__if_exists name|__if_not_exists name|lambda|block|"
+ "type constraint|requirement|requires clause}0 "
"contains%plural{0: an|:}1 unexpanded parameter pack"
"%plural{0:|1: %2|2:s %2 and %3|:s %2, %3, ...}1">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a35a3c2c26c22ad..731d0886a7367dc 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8842,6 +8842,9 @@ class Sema final {
/// The type of an exception.
UPPC_ExceptionType,
+ /// Explicit specialization.
+ UPPC_ExplicitSpecialization,
+
/// Partial specialization.
UPPC_PartialSpecialization,
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6865e04b94b2050..766ebd90fded0c4 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4559,7 +4559,9 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
// Check for unexpanded parameter packs in any of the template arguments.
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
if (DiagnoseUnexpandedParameterPack(TemplateArgs[I],
- UPPC_PartialSpecialization))
+ IsPartialSpecialization
+ ? UPPC_PartialSpecialization
+ : UPPC_ExplicitSpecialization))
return true;
// Check that the template argument list is well-formed for this
@@ -8744,7 +8746,9 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
// Check for unexpanded parameter packs in any of the template arguments.
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
if (DiagnoseUnexpandedParameterPack(TemplateArgs[I],
- UPPC_PartialSpecialization))
+ isPartialSpecialization
+ ? UPPC_PartialSpecialization
+ : UPPC_ExplicitSpecialization))
return true;
// Check that the template argument list is well-formed for this
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 7536339c14a2e08..30ce6b40e1fb5f0 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -369,9 +369,39 @@ void test_unexpanded_exprs(Types ...values) {
void f(int arg = values); // expected-error{{default argument contains unexpanded parameter pack 'values'}}
}
-// Test unexpanded parameter packs in partial specializations.
-template<typename ...Types>
-struct TestUnexpandedDecls<int, Types>; // expected-error{{partial specialization contains unexpanded parameter pack 'Types'}}
+// Test unexpanded parameter packs in partial/explicit specializations.
+namespace Specializations {
+ template<typename T, typename... Ts>
+ struct PrimaryClass;
+ template<typename... Ts>
+ struct PrimaryClass<Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+
+#if __cplusplus >= 201402L
+ template<typename T, typename... Ts>
+ constexpr int PrimaryVar = 0;
+ template<typename... Ts>
+ constexpr int PrimaryVar<Ts> = 0; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+#endif
+
+ template<typename... Ts>
+ struct OuterClass {
+ template<typename... Us>
+ struct InnerClass;
+ template<>
+ struct InnerClass<Ts>; // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}
+ template<typename U>
+ struct InnerClass<U, Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+
+#if __cplusplus >= 201402L
+ template<typename... Us>
+ constexpr static int InnerVar = 0;
+ template<>
+ constexpr static int InnerVar<Ts> = 0; // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}
+ template<typename U>
+ constexpr static int InnerVar<U, Ts> = 0; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+#endif
+ };
+}
// Test for diagnostics in the presence of multiple unexpanded
// parameter packs.
More information about the cfe-commits
mailing list