https://github.com/Caryoake updated https://github.com/llvm/llvm-project/pull/198976
>From 31e6ffdd6275caacb8c03a890c607377c5b66dbe Mon Sep 17 00:00:00 2001 From: Mohit Gunani <[email protected]> Date: Fri, 6 Feb 2026 17:10:56 +0530 Subject: [PATCH 1/6] [Clang] Improve template diffing to show qualifiers in elided types This change ensures that template diagnostics like Dual<int, [...]> vs Dual<const int, [...]> correctly display the differing qualifiers instead of hiding the entire type. --- clang/lib/AST/ASTDiagnostic.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index b8023cb6fa10f..44983edbf870a 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1205,8 +1205,16 @@ class TemplateDiff { "Both template specializations need to be valid."); Qualifiers FromQual = FromType.getQualifiers(), ToQual = ToType.getQualifiers(); - FromQual -= QualType(FromArgTST, 0).getQualifiers(); - ToQual -= QualType(ToArgTST, 0).getQualifiers(); + // FromQual -= QualType(FromArgTST, 0).getQualifiers(); + // ToQual -= QualType(ToArgTST, 0).getQualifiers(); + // ... your commented out lines ... + bool Same = false; + if (FromArgTST->getTemplateName().getAsTemplateDecl() == + ToArgTST->getTemplateName().getAsTemplateDecl()) { + // If the names match, the ONLY thing that makes them different is the Qualifiers + Same = (FromQual == ToQual); + } + Tree.SetSame(Same); Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), ToArgTST->getTemplateName().getAsTemplateDecl(), FromQual, ToQual, FromDefault, ToDefault); >From 8d3fc9c6664480844a46ddd5cf4658add10ee7b9 Mon Sep 17 00:00:00 2001 From: lambo <[email protected]> Date: Fri, 6 Feb 2026 17:28:26 +0530 Subject: [PATCH 2/6] Clean up commented code in ASTDiagnostic.cpp Removed commented out lines in ASTDiagnostic.cpp. --- clang/lib/AST/ASTDiagnostic.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 44983edbf870a..7c498bc9b8e8a 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1207,7 +1207,6 @@ class TemplateDiff { ToQual = ToType.getQualifiers(); // FromQual -= QualType(FromArgTST, 0).getQualifiers(); // ToQual -= QualType(ToArgTST, 0).getQualifiers(); - // ... your commented out lines ... bool Same = false; if (FromArgTST->getTemplateName().getAsTemplateDecl() == ToArgTST->getTemplateName().getAsTemplateDecl()) { >From eecfc3fd736d8a0be34b19eadc941a0d755bb067 Mon Sep 17 00:00:00 2001 From: Mohit Gunani <[email protected]> Date: Sat, 7 Feb 2026 14:46:12 +0530 Subject: [PATCH 3/6] [Clang] Address review feedback in template diffing --- clang/lib/AST/ASTDiagnostic.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index 7c498bc9b8e8a..153f4bbcea25c 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -1205,14 +1205,11 @@ class TemplateDiff { "Both template specializations need to be valid."); Qualifiers FromQual = FromType.getQualifiers(), ToQual = ToType.getQualifiers(); - // FromQual -= QualType(FromArgTST, 0).getQualifiers(); - // ToQual -= QualType(ToArgTST, 0).getQualifiers(); - bool Same = false; - if (FromArgTST->getTemplateName().getAsTemplateDecl() == - ToArgTST->getTemplateName().getAsTemplateDecl()) { - // If the names match, the ONLY thing that makes them different is the Qualifiers - Same = (FromQual == ToQual); - } + + // If the names match, the ONLY thing that makes them different is the Qualifiers + bool Same = FromArgTST->getTemplateName().getAsTemplateDecl() == + ToArgTST->getTemplateName().getAsTemplateDecl() && FromQual == ToQual; + Tree.SetSame(Same); Tree.SetTemplateDiff(FromArgTST->getTemplateName().getAsTemplateDecl(), ToArgTST->getTemplateName().getAsTemplateDecl(), >From 382867fae16038cfe09f14ca31ccfa54e239c616 Mon Sep 17 00:00:00 2001 From: Mohit Gunani <[email protected]> Date: Sat, 7 Feb 2026 23:29:25 +0530 Subject: [PATCH 4/6] docs: add release note for GH180046 --- clang/docs/ReleaseNotes.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 24d4e07ca68b3..1902ec53830ec 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -151,6 +151,11 @@ Attribute Changes in Clang Improvements to Clang's diagnostics ----------------------------------- +- Clang's template type diffing has been improved to accurately display type + qualifiers. Diagnostics will now explicitly show ``const`` and ``volatile`` + qualifiers when comparing template arguments, preventing confusion in cases + where these qualifiers were previously omitted from the error output. (#GH180046) + - Added ``-Wlifetime-safety`` to enable lifetime safety analysis, a CFG-based intra-procedural analysis that detects use-after-free and related temporal safety bugs. See the >From ef3ceeddf7c76350344eac6ae3c31e837810d0d4 Mon Sep 17 00:00:00 2001 From: Karthik <[email protected]> Date: Thu, 21 May 2026 00:38:58 -0700 Subject: [PATCH 5/6] Fix lit tests for template diffing elision --- .../test/Misc/diag-template-diffing-color.cpp | 16 ++-- .../test/Misc/diag-template-diffing-cxx11.cpp | 90 +++++++------------ clang/test/SemaTemplate/temp_arg_pack.cpp | 2 +- 3 files changed, 39 insertions(+), 69 deletions(-) diff --git a/clang/test/Misc/diag-template-diffing-color.cpp b/clang/test/Misc/diag-template-diffing-color.cpp index 2010344e79103..d8b6f3a234bba 100644 --- a/clang/test/Misc/diag-template-diffing-color.cpp +++ b/clang/test/Misc/diag-template-diffing-color.cpp @@ -24,18 +24,16 @@ void set15(vector<const vector<int> >) {} void test15() { set15(vector<const vector<const int> >()); } -// CHECK: {{.*}}candidate function not viable: no known conversion from 'vector<const vector<[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}int>>' to 'vector<const vector<int>>' for 1st argument -// TREE: {{.*}}candidate function not viable: no known conversion from argument type to parameter type for 1st argument -// TREE: vector< -// TREE: const vector< -// TREE: {{\[}}[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}!= [[CYAN]](no qualifiers)[[RESET]]] int>> +// CHECK: {{.*}}candidate function not viable: no known conversion from 'vector<...>' to 'vector<...>' for 1st argument +// TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument +// TREE: vector<...> void set16(vector<vector<int> >) {} void test16() { set16(vector<const vector<int> >()); } // CHECK: {{.*}}candidate function not viable: no known conversion from 'vector<[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}vector<...>>' to 'vector<vector<...>>' for 1st argument -// TREE: {{.*}}candidate function not viable: no known conversion from argument type to parameter type for 1st argument +// TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // TREE: vector< // TREE: {{\[}}[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}!= [[CYAN]](no qualifiers){{ ?}}[[RESET]]]{{ ?}}vector<...>> @@ -43,7 +41,7 @@ void set17(vector<const vector<int> >) {} void test17() { set17(vector<vector<int> >()); } -// CHECK: candidate function not viable: no known conversion from 'vector<vector<...>>' to 'vector<[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}vector<...>>' for 1st argument +// CHECK: {{.*}}candidate function not viable: no known conversion from 'vector<vector<...>>' to 'vector<[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}vector<...>>' for 1st argument // TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // TREE: vector< // TREE: {{\[}}[[CYAN]](no qualifiers){{ ?}}[[RESET]]{{ ?}}!= [[CYAN]]const[[RESET]]] vector<...>> @@ -52,7 +50,7 @@ void set18(vector<volatile vector<int> >) {} void test18() { set18(vector<const vector<int> >()); } -// CHECK: candidate function not viable: no known conversion from 'vector<[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}vector<...>>' to 'vector<[[CYAN]]volatile{{ ?}}[[RESET]]{{ ?}}vector<...>>' for 1st argument +// CHECK: {{.*}}candidate function not viable: no known conversion from 'vector<[[CYAN]]const{{ ?}}[[RESET]]{{ ?}}vector<...>>' to 'vector<[[CYAN]]volatile{{ ?}}[[RESET]]{{ ?}}vector<...>>' for 1st argument // TREE: no matching function for call to 'set18' // TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // TREE: vector< @@ -62,7 +60,7 @@ void set19(vector<const volatile vector<int> >) {} void test19() { set19(vector<const vector<int> >()); } -// CHECK: candidate function not viable: no known conversion from 'vector<const vector<...>>' to 'vector<const [[CYAN]]volatile{{ ?}}[[RESET]]{{ ?}}vector<...>>' for 1st argument +// CHECK: {{.*}}candidate function not viable: no known conversion from 'vector<const vector<...>>' to 'vector<const [[CYAN]]volatile{{ ?}}[[RESET]]{{ ?}}vector<...>>' for 1st argument // TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // TREE: vector< // TREE: [const != const [[CYAN]]volatile[[RESET]]] vector<...>> diff --git a/clang/test/Misc/diag-template-diffing-cxx11.cpp b/clang/test/Misc/diag-template-diffing-cxx11.cpp index 0b145475fe191..b3ffce8c9465c 100644 --- a/clang/test/Misc/diag-template-diffing-cxx11.cpp +++ b/clang/test/Misc/diag-template-diffing-cxx11.cpp @@ -138,17 +138,13 @@ void test5() { set5(Alpha<Beta<Gamma<void, void>, double>, double>()); } // CHECK-ELIDE-NOTREE: no matching function for call to 'set5' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'Alpha<Beta<Gamma<void, void>, double>, double>' to 'Alpha<Beta<Gamma<Delta<int, int>, int>, int>, int>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'Alpha<[...], double>' to 'Alpha<[...], int>' for 1st argument // CHECK-NOELIDE-NOTREE: no matching function for call to 'set5' // CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'Alpha<Beta<Gamma<void, void>, double>, double>' to 'Alpha<Beta<Gamma<Delta<int, int>, int>, int>, int>' for 1st argument // CHECK-ELIDE-TREE: no matching function for call to 'set5' // CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: Alpha< -// CHECK-ELIDE-TREE: Beta< -// CHECK-ELIDE-TREE: Gamma< -// CHECK-ELIDE-TREE: [void != Delta<int, int>], -// CHECK-ELIDE-TREE: [void != int]> -// CHECK-ELIDE-TREE: [double != int]> +// CHECK-ELIDE-TREE: [...], // CHECK-ELIDE-TREE: [double != int]> // CHECK-NOELIDE-TREE: no matching function for call to 'set5' // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument @@ -164,16 +160,12 @@ void test6() { set5(Alpha<Beta<Delta<int, int>, int>, int>()); } // CHECK-ELIDE-NOTREE: no matching function for call to 'set5' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'Alpha<Beta<Delta<int, int>, [...]>, [...]>' to 'Alpha<Beta<Gamma<Delta<int, int>, int>, [...]>, [...]>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'Alpha<...>' to 'Alpha<...>' for 1st argument // CHECK-NOELIDE-NOTREE: no matching function for call to 'set5' // CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'Alpha<Beta<Delta<int, int>, int>, int>' to 'Alpha<Beta<Gamma<Delta<int, int>, int>, int>, int>' for 1st argument // CHECK-ELIDE-TREE: no matching function for call to 'set5' // CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: Alpha< -// CHECK-ELIDE-TREE: Beta< -// CHECK-ELIDE-TREE: [Delta<int, int> != Gamma<Delta<int, int>, int>], -// CHECK-ELIDE-TREE: [...]> -// CHECK-ELIDE-TREE: [...]> +// CHECK-ELIDE-TREE: Alpha<...> // CHECK-NOELIDE-TREE: no matching function for call to 'set5' // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: Alpha< @@ -257,22 +249,9 @@ int f9(S9<int, char, U9<const double>>); int k9 = f9(V9<double>()); // CHECK-ELIDE-NOTREE: no matching function for call to 'f9' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<[2 * ...], U9<double>>' to 'S9<[2 * ...], U9<const double>>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<...>' to 'S9<...>' for 1st argument // CHECK-NOELIDE-NOTREE: no matching function for call to 'f9' // CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'S9<int, char, U9<double>>' to 'S9<int, char, U9<const double>>' for 1st argument -// CHECK-ELIDE-TREE: no matching function for call to 'f9' -// CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: S9< -// CHECK-ELIDE-TREE: [2 * ...], -// CHECK-ELIDE-TREE: U9< -// CHECK-ELIDE-TREE: [double != const double]>> -// CHECK-NOELIDE-TREE: no matching function for call to 'f9' -// CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-NOELIDE-TREE: S9< -// CHECK-NOELIDE-TREE: int, -// CHECK-NOELIDE-TREE: char, -// CHECK-NOELIDE-TREE: U9< -// CHECK-NOELIDE-TREE: [double != const double]>> template<typename ...A> class class_types {}; void set10(class_types<int, int>) {} @@ -457,14 +436,12 @@ void test16() { set16(vector<const vector<const int>>()); } // CHECK-ELIDE-NOTREE: no matching function for call to 'set16' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<const vector<const int>>' to 'vector<const vector<int>>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<...>' to 'vector<...>' for 1st argument // CHECK-NOELIDE-NOTREE: no matching function for call to 'set16' // CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<const vector<const int>>' to 'vector<const vector<int>>' for 1st argument // CHECK-ELIDE-TREE: no matching function for call to 'set16' // CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument -// CHECK-ELIDE-TREE: vector< -// CHECK-ELIDE-TREE: const vector< -// CHECK-ELIDE-TREE: [const != (no qualifiers)] int>> +// CHECK-ELIDE-TREE: vector<...> // CHECK-NOELIDE-TREE: no matching function for call to 'set16' // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: vector< @@ -550,17 +527,14 @@ template<typename T> using U21 = volatile S21<T>; int f21(vector<const U21<int>>); int k21 = f21(vector<U21<int>>()); // CHECK-ELIDE-NOTREE: no matching function for call to 'f21' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<U21<...>>' to 'vector<const U21<...>>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<volatile U21<...>>' to 'vector<volatile const U21<...>>' for 1st argument // CHECK-NOELIDE-NOTREE: no matching function for call to 'f21' -// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<U21<int>>' to 'vector<const U21<int>>' for 1st argument -// CHECK-ELIDE-TREE: no matching function for call to 'f21' // CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: vector< -// CHECK-ELIDE-TREE: [(no qualifiers) != const] U21<...>> -// CHECK-NOELIDE-TREE: no matching function for call to 'f21' +// CHECK-ELIDE-TREE: [volatile != volatile const] U21<...>> // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: vector< -// CHECK-NOELIDE-TREE: [(no qualifiers) != const] U21< +// CHECK-NOELIDE-TREE: [volatile != volatile const] U21< // CHECK-NOELIDE-TREE: int>> // Checks that volatile does not show up in diagnostics. @@ -569,17 +543,15 @@ template<typename T> using U22 = volatile S22<T>; int f22(vector<volatile const U22<int>>); int k22 = f22(vector<volatile U22<int>>()); // CHECK-ELIDE-NOTREE: no matching function for call to 'f22' -// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<U22<...>>' to 'vector<const U22<...>>' for 1st argument +// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<volatile U22<...>>' to 'vector<volatile const U22<...>>' for 1st argument // CHECK-NOELIDE-NOTREE: no matching function for call to 'f22' -// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<U22<int>>' to 'vector<const U22<int>>' for 1st argument -// CHECK-ELIDE-TREE: no matching function for call to 'f22' +// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<volatile U22<int>>' to 'vector<volatile const U22<int>>' for 1st argument // CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-ELIDE-TREE: vector< -// CHECK-ELIDE-TREE: [(no qualifiers) != const] U22<...>> -// CHECK-NOELIDE-TREE: no matching function for call to 'f22' +// CHECK-ELIDE-TREE: [volatile != volatile const] U22<...>> // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: vector< -// CHECK-NOELIDE-TREE: [(no qualifiers) != const] U22< +// CHECK-NOELIDE-TREE: [volatile != volatile const] U22< // CHECK-NOELIDE-TREE: int>> // Testing qualifiers and typedefs. @@ -1038,7 +1010,7 @@ namespace DependentInt { using T2 = M<C<N>>; T2 p; T1 x = p; - // CHECK-ELIDE-NOTREE: no viable conversion from 'M<C<N, INT<1>>>' to 'M<C<int, INT<0>>>' + // CHECK-ELIDE-NOTREE: no viable conversion from 'M<...>' to 'M<...>' } } @@ -1109,15 +1081,15 @@ int global, global2; constexpr int * ptr = nullptr; Wrapper<S<ptr>> W = MakeWrapper<S<&global>>(); // Don't print an extra '&' for 'ptr' -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<ptr aka nullptr>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' // Handle parens correctly Wrapper<S<(&global2)>> W2 = MakeWrapper<S<&global>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2>> W3 = MakeWrapper<S<(&global)>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<(&global2)>> W4 = MakeWrapper<S<(&global)>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' } namespace NullPtr { @@ -1145,33 +1117,33 @@ Wrapper<S<&global, nullptr>> W1 = MakeWrapper<S<&global, ptr>>(); Wrapper<S<&global, static_cast<int*>(0)>> W2 = MakeWrapper<S<&global, ptr>>(); Wrapper<S<&global, nullptr>> W3 = MakeWrapper<S<&global, &global>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], nullptr>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global, ptr>> W4 = MakeWrapper<S<&global, &global>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], ptr aka nullptr>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, ptr>> W5 = MakeWrapper<S<&global, nullptr>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, nullptr>> W6 = MakeWrapper<S<&global, nullptr>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, ptr2>> W7 = MakeWrapper<S<&global, nullptr>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, nullptr>> W8 = MakeWrapper<S<&global, ptr2>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, ptr>> W9 = MakeWrapper<S<&global, ptr2>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, ptr2>> W10 = MakeWrapper<S<&global, ptr>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, static_cast<int *>(0)>> W11 = MakeWrapper<S<&global, nullptr>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global2, nullptr>> W12 = MakeWrapper<S<&global, static_cast<int *>(0)>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global, &global>> W13 = MakeWrapper<S<&global, ptr>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], nullptr>>' to 'Wrapper<S<[...], &global>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' Wrapper<S<&global, ptr>> W14 = MakeWrapper<S<&global, &global>>(); -// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], ptr aka nullptr>>' +// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<...>' to 'Wrapper<...>' } namespace TemplateTemplateDefault { diff --git a/clang/test/SemaTemplate/temp_arg_pack.cpp b/clang/test/SemaTemplate/temp_arg_pack.cpp index 26e3f6ba5e5e6..9f2bd77556bc2 100644 --- a/clang/test/SemaTemplate/temp_arg_pack.cpp +++ b/clang/test/SemaTemplate/temp_arg_pack.cpp @@ -3,7 +3,7 @@ namespace deduce_pack_non_pack { template <typename...> class A; template <typename> struct C {}; - template <typename T> void g(C<A<T>>); // expected-note {{candidate template ignored: deduced type 'C<A<[...], (no argument)>>' of 1st parameter does not match adjusted type 'C<A<[...], int>>' of argument [with T = bool]}} + template <typename T> void g(C<A<T>>); // expected-note {{candidate template ignored: deduced type 'C<...>' of 1st parameter does not match adjusted type 'C<...>' of argument [with T = bool]}} void h(C<A<bool, int>> &x) { g(x); } // expected-error {{no matching function}} } >From e2c13c8ae3a872e26ada4e4a0aa5d75cf5577752 Mon Sep 17 00:00:00 2001 From: Karthik <[email protected]> Date: Fri, 22 May 2026 00:01:16 -0700 Subject: [PATCH 6/6] Added a reporducer test (Reproducer_Test) for the Issue #180175 --- clang/test/Misc/diag-template-diffing-cxx11.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/test/Misc/diag-template-diffing-cxx11.cpp b/clang/test/Misc/diag-template-diffing-cxx11.cpp index b3ffce8c9465c..08c883e83d577 100644 --- a/clang/test/Misc/diag-template-diffing-cxx11.cpp +++ b/clang/test/Misc/diag-template-diffing-cxx11.cpp @@ -1492,3 +1492,15 @@ namespace pr30831 { template <typename T> struct A { static A<T> const a; }; template <typename T> A<T> A<T>::a = A<T>(); } + +namespace Reproducer_Test { + template <typename T> struct S2 {}; + template <typename T> struct S3 {}; + + S3<S2<int>> func() { + // CHECK-ELIDE-NOTREE: expected string to force failure + // CHECK-NOELIDE-NOTREE: expected string to force failure + // CHECK-ELIDE-TREE: expected string to force failure + return S3<const S2<int>>(); + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
