From: Douglas Gregor Date: Thu, 29 Apr 2010 06:31:36 +0000 (+0000) Subject: When performing partial ordering of class template partial X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=516e6e09821a61e8975c787e189949723249e7c5;p=clang 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 --- 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]; +}