mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
When performing template argument deduction to select a partial
specialization while substituting a partial template parameter pack, don't try to extend the existing deduction. This caused us to select the wrong partial specialization in some rare cases. A recent change to libc++ caused this to happen in practice for code using std::conjunction.
This commit is contained in:
parent
909a5ccf3b
commit
6bbfa0fd40
@ -3079,6 +3079,10 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
|
||||
*this, Sema::ExpressionEvaluationContext::Unevaluated);
|
||||
SFINAETrap Trap(*this);
|
||||
|
||||
// This deduction has no relation to any outer instantiation we might be
|
||||
// performing.
|
||||
LocalInstantiationScope InstantiationScope(*this);
|
||||
|
||||
SmallVector<DeducedTemplateArgument, 4> Deduced;
|
||||
Deduced.resize(Partial->getTemplateParameters()->size());
|
||||
if (TemplateDeductionResult Result
|
||||
@ -3127,6 +3131,10 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
|
||||
*this, Sema::ExpressionEvaluationContext::Unevaluated);
|
||||
SFINAETrap Trap(*this);
|
||||
|
||||
// This deduction has no relation to any outer instantiation we might be
|
||||
// performing.
|
||||
LocalInstantiationScope InstantiationScope(*this);
|
||||
|
||||
SmallVector<DeducedTemplateArgument, 4> Deduced;
|
||||
Deduced.resize(Partial->getTemplateParameters()->size());
|
||||
if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
|
||||
|
@ -112,3 +112,25 @@ namespace InstantiationDependent {
|
||||
_Static_assert(!A<X>::specialized, "");
|
||||
_Static_assert(A<Y>::specialized, "");
|
||||
}
|
||||
|
||||
namespace IgnorePartialSubstitution {
|
||||
template <typename... T> struct tuple {}; // expected-warning 0-1{{extension}}
|
||||
template <typename> struct IsTuple {
|
||||
enum { value = false };
|
||||
};
|
||||
template <typename... Us> struct IsTuple<tuple<Us...> > { // expected-warning 0-1{{extension}}
|
||||
enum { value = true };
|
||||
};
|
||||
|
||||
template <bool...> using ignore = void; // expected-warning 0-2{{extension}}
|
||||
template <class... Pred> ignore<Pred::value...> helper(); // expected-warning 0-1{{extension}}
|
||||
|
||||
using S = IsTuple<tuple<int> >; // expected-warning 0-1{{extension}}
|
||||
|
||||
// This used to pick the primary template, because we got confused and
|
||||
// thought that template parameter 0 was the current partially-substituted
|
||||
// pack (from `helper`) during the deduction for the partial specialization.
|
||||
void f() { helper<S>(); }
|
||||
|
||||
_Static_assert(S::value, "");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user