summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2020-01-15 13:14:13 -0800
committerHans Wennborg <hans@chromium.org>2020-01-17 09:52:57 +0100
commite241c8fe6d2e6d83e9fb32bd34da8ffcdc0dd83d (patch)
tree183c25cd7c7a5bf434bfa6c03f1dfe6b0281a02c /clang/lib/Sema
parent7a8b8f09daa1d4f8b82275006678ce3b5daa03b2 (diff)
downloadbcm5719-llvm-e241c8fe6d2e6d83e9fb32bd34da8ffcdc0dd83d.tar.gz
bcm5719-llvm-e241c8fe6d2e6d83e9fb32bd34da8ffcdc0dd83d.zip
Fix pack deduction to only deduce the arity of packs that are actually
expanded by the deduced pack. We recently started also deducing the arity of separately-expanded packs that are merely mentioned within the pack in question, which is incorrect. (cherry picked from commit e8f198dd9e9dabed8d50276465906e7c8827cada)
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp50
1 files changed, 30 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 1b9f1b2144d..048a50a741e 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -724,38 +724,48 @@ private:
// Compute the set of template parameter indices that correspond to
// parameter packs expanded by the pack expansion.
llvm::SmallBitVector SawIndices(TemplateParams->size());
+ llvm::SmallVector<TemplateArgument, 4> ExtraDeductions;
auto AddPack = [&](unsigned Index) {
if (SawIndices[Index])
return;
SawIndices[Index] = true;
addPack(Index);
+
+ // Deducing a parameter pack that is a pack expansion also constrains the
+ // packs appearing in that parameter to have the same deduced arity. Also,
+ // in C++17 onwards, deducing a non-type template parameter deduces its
+ // type, so we need to collect the pending deduced values for those packs.
+ if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
+ TemplateParams->getParam(Index))) {
+ if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType()))
+ ExtraDeductions.push_back(Expansion->getPattern());
+ }
+ // FIXME: Also collect the unexpanded packs in any type and template
+ // parameter packs that are pack expansions.
};
- // First look for unexpanded packs in the pattern.
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
- for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
- if (Depth == Info.getDeducedDepth())
- AddPack(Index);
- }
+ auto Collect = [&](TemplateArgument Pattern) {
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
+ for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
+ unsigned Depth, Index;
+ std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
+ if (Depth == Info.getDeducedDepth())
+ AddPack(Index);
+ }
+ };
+
+ // Look for unexpanded packs in the pattern.
+ Collect(Pattern);
assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
unsigned NumNamedPacks = Packs.size();
- // We can also have deduced template parameters that do not actually
- // appear in the pattern, but can be deduced by it (the type of a non-type
- // template parameter pack, in particular). These won't have prevented us
- // from partially expanding the pack.
- llvm::SmallBitVector Used(TemplateParams->size());
- MarkUsedTemplateParameters(S.Context, Pattern, /*OnlyDeduced*/true,
- Info.getDeducedDepth(), Used);
- for (int Index = Used.find_first(); Index != -1;
- Index = Used.find_next(Index))
- if (TemplateParams->getParam(Index)->isParameterPack())
- AddPack(Index);
+ // Also look for unexpanded packs that are indirectly deduced by deducing
+ // the sizes of the packs in this pattern.
+ while (!ExtraDeductions.empty())
+ Collect(ExtraDeductions.pop_back_val());
return NumNamedPacks;
}
OpenPOWER on IntegriCloud