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
This commit is contained in:
Douglas Gregor 2010-04-29 06:31:36 +00:00
Родитель 31dce8f606
Коммит 516e6e0982
2 изменённых файлов: 41 добавлений и 1 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -14,3 +14,35 @@ template<int I> struct X<I, I, int> {
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<typename T, typename U = void, typename V = void>
struct X {
static const unsigned value = 1;
};
template<typename T, typename U>
struct X<T, U, typename T::is_b> {
static const unsigned value = 2;
};
template<typename T>
struct X<T, typename T::is_a, typename T::is_b> {
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<X1, void, void>::value == 1? 1 : -1];
int check_X2[X<X2, void, void>::value == 2? 1 : -1];
int check_X3[X<X3, void, void>::value == 3? 1 : -1];
}