[clang] [Clang][Sema] Differentiate between partial/explicit specializations when diagnosing unexpanded packs (PR #72015)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 10 18:31:18 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Krystian Stasiowski (sdkrystian)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/72015.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3-3) 
- (modified) clang/include/clang/Sema/Sema.h (+3) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+6-2) 
- (modified) clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (+32-3) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4614324babb1c91..0c8f07b095b1eaa 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 f69f366c1750918..e59827b8c281ea1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8839,6 +8839,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..d00630b0258a734 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,38 @@ 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 T, typename... Ts>
+  constexpr int PrimaryVar = 0;
+
+  template<typename... Ts>
+  struct PrimaryClass<Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+
+  template<typename... Ts>
+  constexpr int PrimaryVar<Ts> = 0; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+
+  template<typename... Ts>
+  struct OuterClass {
+    template<typename... Us>
+    struct InnerClass;
+    template<typename... Us>
+    constexpr static int InnerVar = 0;
+
+    template<>
+    struct InnerClass<Ts>; // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}
+    template<>
+    constexpr static int InnerVar<Ts> = 0; // 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'}}
+    template<typename U>
+    constexpr static int InnerVar<U, Ts> = 0; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}
+  };
+}
 
 // Test for diagnostics in the presence of multiple unexpanded
 // parameter packs.

``````````

</details>


https://github.com/llvm/llvm-project/pull/72015


More information about the cfe-commits mailing list