diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-06-07 02:42:27 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-06-07 02:42:27 +0000 |
commit | 2695ac7becb347f62273040501dc6b858ddd68e9 (patch) | |
tree | c03dc51a7188865a87af9b6a754db9bc6d7dbf95 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 260b4fb81be86886d2f59664a06a10b7533be194 (diff) |
Fix a couple of class template argument deduction crashes with libc++'s tuple.
RecursiveASTVisitor was not properly recursing through a
SubstTemplateTypeParmTypes, resulting in crashes in pack expansion where we
couldn't always find an unexpanded pack within a pack expansion.
We also have an issue where substitution of deduced template arguments for an
implicit deduction guide creates the "impossible" case of naming a
non-dependent member of the current instantiation, but within a specialization
that is actually instantiated from a different (partial/explicit)
specialization of the template. We resolve this by declaring that constructors
that do so can only be used to deduce specializations of the primary template.
I'm running this past CWG to see if people agree this is the right thing to do.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304862 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index a654ca800b..2279c9ca55 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -2350,6 +2350,25 @@ namespace { }; } +bool Sema::usesPartialOrExplicitSpecialization( + SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec) { + if (ClassTemplateSpec->getTemplateSpecializationKind() == + TSK_ExplicitSpecialization) + return true; + + SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; + ClassTemplateSpec->getSpecializedTemplate() + ->getPartialSpecializations(PartialSpecs); + for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) { + TemplateDeductionInfo Info(Loc); + if (!DeduceTemplateArguments(PartialSpecs[I], + ClassTemplateSpec->getTemplateArgs(), Info)) + return true; + } + + return false; +} + /// Get the instantiation pattern to use to instantiate the definition of a /// given ClassTemplateSpecializationDecl (either the pattern of the primary /// template or of a partial specialization). |