summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-02-21 08:42:39 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-02-21 08:42:39 +0000
commit0cd9c0491e90ed23f9f5069ae86837d77bfa26c9 (patch)
tree76aae2993b214795cef212fbbe502e3a2db0a601 /clang
parentfe78d95a4956840baa350432fa2dac0e242693ab (diff)
downloadbcm5719-llvm-0cd9c0491e90ed23f9f5069ae86837d77bfa26c9.tar.gz
bcm5719-llvm-0cd9c0491e90ed23f9f5069ae86837d77bfa26c9.zip
Fix lookup through injected-class-names in implicit deduction guides in the
case where the class template has a parameter pack. Checking of the template arguments expects an "as-written" template argument list, which in particular does not have any parameter packs. So flatten the packs into separate arguments before passing them in. llvm-svn: 295710
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp14
-rw-r--r--clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp21
2 files changed, 27 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b285d4f3814..7ccbb8571c5 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4957,11 +4957,17 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD);
if (Guide && Guide->isImplicit()) {
TemplateDecl *TD = Guide->getDeducedTemplate();
+ // Convert the arguments to an "as-written" list.
TemplateArgumentListInfo Args(Loc, Loc);
- for (auto Arg : TemplateArgs.getInnermost().take_front(
- TD->getTemplateParameters()->size()))
- Args.addArgument(
- getTrivialTemplateArgumentLoc(Arg, QualType(), Loc));
+ for (TemplateArgument Arg : TemplateArgs.getInnermost().take_front(
+ TD->getTemplateParameters()->size())) {
+ ArrayRef<TemplateArgument> Unpacked(Arg);
+ if (Arg.getKind() == TemplateArgument::Pack)
+ Unpacked = Arg.pack_elements();
+ for (TemplateArgument UnpackedArg : Unpacked)
+ Args.addArgument(
+ getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc));
+ }
QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
if (T.isNull())
return nullptr;
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index 8c96fb4fd0f..750a0892917 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -194,9 +194,22 @@ namespace transform_params {
A a(qn, qn); // expected-error {{no matching constructor for initialization of 'transform_params::A<int, 12, Q, &transform_params::n>'}}
static_assert(a.v == 12);
- // FIXME: This should be accepted.
- template<typename ...T> struct B { // expected-note {{candidate}}
- template<T ...V> B(const T (&...p)[V]); // expected-note {{substitution failure}}
+ template<typename ...T> struct B {
+ template<T ...V> B(const T (&...p)[V]) {
+ constexpr int Vs[] = {V...};
+ static_assert(Vs[0] == 3 && Vs[1] == 4 && Vs[2] == 4);
+ }
+ static constexpr int (*p)(T...) = (int(*)(int, char, char))nullptr;
};
- B b({1, 2, 3}, {"foo", "bar"}, {'x', 'y', 'z', 'w'}); // expected-error {{no viable constructor or deduction guide}}
+ B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok
+
+ template<typename ...T> struct C { // expected-note {{candidate}}
+ template<T ...V, template<T...> typename X>
+ C(X<V...>); // expected-note {{substitution failure [with T = <>, V = <0, 1, 2>]}}
+ };
+ template<int...> struct Y {};
+ // FIXME: This incorrectly deduces T = <>, rather than deducing
+ // T = <int, int, int> from the types of the elements of V.
+ // (This failure is not related to class template argument deduction.)
+ C c(Y<0, 1, 2>{}); // expected-error {{no viable constructor or deduction guide}}
}
OpenPOWER on IntegriCloud