[clang] [Clang] Fix another parameter mapping substitution bug (PR #162155)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 6 13:36:51 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Corentin Jabot (cor3ntin)

<details>
<summary>Changes</summary>

When a template parameter pack is named before
it can be substituted, it might not have a corresponding mapping.

Fixes #<!-- -->162125

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


2 Files Affected:

- (modified) clang/lib/Sema/SemaConcept.cpp (+2-1) 
- (modified) clang/test/SemaTemplate/concepts.cpp (+40-1) 


``````````diff
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 999e302c02535..cb42d651a6586 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -277,7 +277,8 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
   bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
     // A lambda expression can introduce template parameters that don't have
     // corresponding template arguments yet.
-    if (T->getDepth() >= TemplateArgs.getNumLevels())
+    if (T->getDepth() >= TemplateArgs.getNumLevels()
+        || !TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex()))
       return true;
 
     TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index e5e081ffb9d0f..3671dc6ff84de 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++20 -ferror-limit 0 -verify %s
+// RUN: %clang_cc1 -std=c++20 -ferror-limit 0 -verify=expected,cxx20 %s
+// RUN: %clang_cc1 -std=c++2c -ferror-limit 0 -verify=expected %s
 
 namespace PR47043 {
   template<typename T> concept True = true;
@@ -1405,3 +1406,41 @@ static_assert(!std::is_constructible_v<span<4>, array<int, 3>>);
 }
 
 }
+
+
+namespace GH162125 {
+template<typename, int size>
+concept true_int = (size, true);
+
+template<typename, typename... Ts>
+concept true_types = true_int<void, sizeof...(Ts)>;
+
+template<typename, typename... Ts>
+concept true_types2 = true_int<void, Ts...[0]{1}>; // cxx20-warning {{pack indexing is a C++2c extension}}
+
+template<typename... Ts>
+struct s {
+  template<typename T> requires true_types<T, Ts...> && true_types2<T, Ts...>
+  static void f(T);
+};
+void(*test)(int) = &s<bool>::f<int>;
+}
+
+namespace GH162125_reversed {
+template<int size, typename>
+concept true_int = (size, true);
+
+template<typename, typename... Ts>
+concept true_types = true_int<sizeof...(Ts), void>;
+
+template<typename, typename... Ts>
+concept true_types2 = true_int<Ts...[0]{1}, void>;
+
+template<typename... Ts>
+struct s {
+  template<typename T> requires true_types<T, Ts...> && true_types2<T, Ts...>
+  static void f(T);
+};
+
+void(*test)(int) = &s<bool>::f<int>;
+}

``````````

</details>


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


More information about the cfe-commits mailing list