diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-04-13 21:37:24 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-04-13 21:37:24 +0000 |
commit | 24a137ec645bd77f10353247a0a63e0a082a11ec (patch) | |
tree | acd31ee7a6231b16035df4e3b34d983d39b1efd1 /test/SemaTemplate | |
parent | 08a97a0d0b15aeb903ab0e12d11a08d805d8db1b (diff) |
PR32185: Revert r291512 and add a testcase for PR32185.
This reverts an attempt to check that types match when matching a
dependently-typed non-type template parameter. (This comes up when matching the
parameters of a template template parameter against the parameters of a
template template argument.)
The matching rules here are murky at best. Our behavior after this revert is
definitely wrong for certain C++17 features (for 'auto' template parameter
types within the parameter list of a template template argument in particular),
but our behavior before this revert is wrong for some pre-existing testcases,
so reverting to our prior behavior seems like our best option.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300262 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r-- | test/SemaTemplate/deduction.cpp | 7 | ||||
-rw-r--r-- | test/SemaTemplate/temp_arg_template.cpp | 41 | ||||
-rw-r--r-- | test/SemaTemplate/temp_arg_template_cxx1z.cpp | 18 |
3 files changed, 50 insertions, 16 deletions
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp index 8ac65aacd5..74eb5a6ee5 100644 --- a/test/SemaTemplate/deduction.cpp +++ b/test/SemaTemplate/deduction.cpp @@ -483,16 +483,15 @@ namespace check_extended_pack { } namespace dependent_template_template_param_non_type_param_type { - template<int N> struct A { // expected-note 2{{candidate}} + template<int N> struct A { template<typename V = int, V M = 12, V (*Y)[M], template<V (*v)[M]> class W> - A(W<Y>); // expected-note {{[with V = int, M = 12, Y = &dependent_template_template_param_non_type_param_type::n]}} + A(W<Y>); }; int n[12]; template<int (*)[12]> struct Q {}; Q<&n> qn; - // FIXME: This should be accepted, but we somehow fail to deduce W. - A<0> a(qn); // expected-error {{no matching constructor for initialization}} + A<0> a(qn); } namespace dependent_list_deduction { diff --git a/test/SemaTemplate/temp_arg_template.cpp b/test/SemaTemplate/temp_arg_template.cpp index b0df9149c6..8f59dd724c 100644 --- a/test/SemaTemplate/temp_arg_template.cpp +++ b/test/SemaTemplate/temp_arg_template.cpp @@ -102,7 +102,42 @@ void foo() { } namespace CheckDependentNonTypeParamTypes { - template<template<typename T, typename U, T v> class> struct A {}; // expected-note {{previous}} - template<typename T, typename U, U v> struct B {}; // expected-note {{different type}} - A<B> ab; // expected-error {{different template parameters}} + template<template<typename T, typename U, T v> class X> struct A { + void f() { + X<int, void*, 3> x; // expected-error {{does not refer to any declaration}} + } + void g() { + X<int, long, 3> x; + } + void h() { + // FIXME: If we accept A<B> at all, it's not obvious what should happen + // here. While parsing the template, we form + // X<unsigned char, int, (unsigned char)1234> + // but in the final instantiation do we get + // B<unsigned char, int, (int)1234> + // or + // B<unsigned char, int, (int)(unsigned char)1234> + // ? + X<unsigned char, int, 1234> x; + int check[x.value == 1234 ? 1 : -1]; + } + }; + + template<typename T, typename U, U v> struct B { // expected-note {{parameter}} + static const U value = v; + }; + + // FIXME: This should probably be rejected, but the rules are at best unclear. + A<B> ab; + + void use() { + ab.f(); // expected-note {{instantiation of}} + ab.g(); + ab.h(); + } +} + +namespace PR32185 { + template<template<typename T, T> class U> struct A {}; + template<template<typename T, T> class U> struct B : A<U> {}; } diff --git a/test/SemaTemplate/temp_arg_template_cxx1z.cpp b/test/SemaTemplate/temp_arg_template_cxx1z.cpp index e3f228e7ef..03ef78f8cf 100644 --- a/test/SemaTemplate/temp_arg_template_cxx1z.cpp +++ b/test/SemaTemplate/temp_arg_template_cxx1z.cpp @@ -78,7 +78,7 @@ namespace Auto { template<int*> struct IntPtr; TInt<Auto> ia; - TInt<AutoPtr> iap; // expected-error {{different template parameters}} + TInt<AutoPtr> iap; // FIXME: ill-formed (?) TInt<DecltypeAuto> ida; TInt<Int> ii; TInt<IntPtr> iip; // expected-error {{different template parameters}} @@ -90,18 +90,18 @@ namespace Auto { TIntPtr<IntPtr> ipip; TAuto<Auto> aa; - TAuto<AutoPtr> aap; // expected-error {{different template parameters}} - TAuto<Int> ai; // expected-error {{different template parameters}} - TAuto<IntPtr> aip; // expected-error {{different template parameters}} + TAuto<AutoPtr> aap; // FIXME: ill-formed (?) + TAuto<Int> ai; // FIXME: ill-formed (?) + TAuto<IntPtr> aip; // FIXME: ill-formed (?) TAutoPtr<Auto> apa; TAutoPtr<AutoPtr> apap; - TAutoPtr<Int> api; // expected-error {{different template parameters}} - TAutoPtr<IntPtr> apip; // expected-error {{different template parameters}} + TAutoPtr<Int> api; // FIXME: ill-formed (?) + TAutoPtr<IntPtr> apip; // FIXME: ill-formed (?) TDecltypeAuto<DecltypeAuto> dada; - TDecltypeAuto<Int> dai; // expected-error {{different template parameters}} - TDecltypeAuto<IntPtr> daip; // expected-error {{different template parameters}} + TDecltypeAuto<Int> dai; // FIXME: ill-formed (?) + TDecltypeAuto<IntPtr> daip; // FIXME: ill-formed (?) // FIXME: It's completely unclear what should happen here, but these results // seem at least plausible: @@ -111,7 +111,7 @@ namespace Auto { // parameters (such as 'user-defined-type &') that are not valid 'auto' // parameters. TDecltypeAuto<Auto> daa; - TDecltypeAuto<AutoPtr> daa; // expected-error {{different template parameters}} + TDecltypeAuto<AutoPtr> daap; // FIXME: should probably be ill-formed int n; template<auto A, decltype(A) B = &n> struct SubstFailure; |