From 516e6e09821a61e8975c787e189949723249e7c5 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 29 Apr 2010 06:31:36 +0000 Subject: [PATCH] When performing partial ordering of class template partial specializations, substitute the deduced template arguments and check the resulting substitution before concluding that template argument deduction succeeds. This marvelous little fix makes a bunch of Boost.Spirit tests start working. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102601 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateDeduction.cpp | 10 +++++- .../temp.class.spec/temp.class.order/p2.cpp | 32 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 031209235c..2bb97eba11 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2384,7 +2384,11 @@ Sema::getMoreSpecializedPartialSpecialization( Info, Deduced, 0); - + if (Better1) + Better1 = !::FinishTemplateArgumentDeduction(*this, PS2, + PS1->getTemplateArgs(), + Deduced, Info); + // Determine whether PS2 is at least as specialized as PS1 Deduced.clear(); Deduced.resize(PS1->getTemplateParameters()->size()); @@ -2395,6 +2399,10 @@ Sema::getMoreSpecializedPartialSpecialization( Info, Deduced, 0); + if (Better2) + Better2 = !::FinishTemplateArgumentDeduction(*this, PS1, + PS2->getTemplateArgs(), + Deduced, Info); if (Better1 == Better2) return 0; diff --git a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp index e344eedfd6..97457ea213 100644 --- a/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp +++ b/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp @@ -14,3 +14,35 @@ template struct X { int array0[X<0, 0, float>::value == 0? 1 : -1]; int array1[X<0, 1, int>::value == 1? 1 : -1]; int array2[X<0, 0, int>::value == 2? 1 : -1]; + +namespace DependentSubstPartialOrdering { + template + struct X { + static const unsigned value = 1; + }; + + template + struct X { + static const unsigned value = 2; + }; + + template + struct X { + static const unsigned value = 3; + }; + + struct X1 { }; + + struct X2 { + typedef void is_b; + }; + + struct X3 { + typedef void is_a; + typedef void is_b; + }; + + int check_X1[X::value == 1? 1 : -1]; + int check_X2[X::value == 2? 1 : -1]; + int check_X3[X::value == 3? 1 : -1]; +} -- 2.40.0