[clang] 6bbfa0f - When performing template argument deduction to select a partial
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed May 5 14:47:29 PDT 2021
Author: Richard Smith
Date: 2021-05-05T14:47:18-07:00
New Revision: 6bbfa0fd408e81055c360c2e059554dd76fd7f09
URL: https://github.com/llvm/llvm-project/commit/6bbfa0fd408e81055c360c2e059554dd76fd7f09
DIFF: https://github.com/llvm/llvm-project/commit/6bbfa0fd408e81055c360c2e059554dd76fd7f09.diff
LOG: 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.
Added:
Modified:
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/test/SemaTemplate/partial-spec-instantiate.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 7d548e4f8dee1..3c66c8eeda8b9 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -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(
diff --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
index 3b7cee88c42ec..369ff69aa3756 100644
--- a/clang/test/SemaTemplate/partial-spec-instantiate.cpp
+++ b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -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, "");
+}
More information about the cfe-commits
mailing list