summaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-04-13 21:37:24 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-04-13 21:37:24 +0000
commit24a137ec645bd77f10353247a0a63e0a082a11ec (patch)
treeacd31ee7a6231b16035df4e3b34d983d39b1efd1 /test/SemaTemplate
parent08a97a0d0b15aeb903ab0e12d11a08d805d8db1b (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.cpp7
-rw-r--r--test/SemaTemplate/temp_arg_template.cpp41
-rw-r--r--test/SemaTemplate/temp_arg_template_cxx1z.cpp18
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;