зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
31dce8f606
Коммит
516e6e0982
|
@ -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];
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче