1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -frelaxed-template-template-args %s
2 
3 // expected-note@temp_arg_template_cxx1z.cpp:* 1+{{}}
4 
5 template<template<int> typename> struct Ti;
6 template<template<int...> typename> struct TPi;
7 template<template<int, int...> typename> struct TiPi;
8 template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed?
9 
10 template<typename T, template<T> typename> struct tT0;
11 template<template<typename T, T> typename> struct Tt0;
12 
13 template<template<typename> typename> struct Tt;
14 template<template<typename, typename...> typename> struct TtPt;
15 
16 template<int> struct i;
17 template<int, int = 0> struct iDi;
18 template<int, int> struct ii;
19 template<int...> struct Pi;
20 template<int, int, int...> struct iiPi;
21 
22 template<int, typename = int> struct iDt;
23 template<int, typename> struct it;
24 
25 template<typename T, T v> struct t0;
26 
27 template<typename...> struct Pt;
28 
29 namespace IntParam {
30   using ok = Pt<Ti<i>,
31         Ti<iDi>,
32         Ti<Pi>,
33         Ti<iDt>>;
34   using err1 = Ti<ii>; // expected-error {{different template parameters}}
35   using err2 = Ti<iiPi>; // expected-error {{different template parameters}}
36   using err3 = Ti<t0>; // expected-error {{different template parameters}}
37   using err4 = Ti<it>; // expected-error {{different template parameters}}
38 }
39 
40 // These are accepted by the backwards-compatibility "parameter pack in
41 // parameter matches any number of parameters in arguments" rule.
42 namespace IntPackParam {
43   using ok = TPi<Pi>;
44   using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>;
45   using err1 = TPi<t0>; // expected-error {{different template parameters}}
46   using err2 = TPi<iDt>; // expected-error {{different template parameters}}
47   using err3 = TPi<it>; // expected-error {{different template parameters}}
48 }
49 
50 namespace IntAndPackParam {
51   using ok = TiPi<Pi>;
52   using ok_compat = Pt<TiPi<ii>, TiPi<iDi>, TiPi<iiPi>>;
53   using err = TiPi<iDi>;
54 }
55 
56 namespace DependentType {
57   using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
58   using err1 = tT0<int, ii>; // expected-error {{different template parameters}}
59   using err2 = tT0<short, i>; // FIXME: should this be OK?
60   using err2a = tT0<long long, i>; // FIXME: should this be OK (if long long is larger than int)?
61   using err2b = tT0<void*, i>; // expected-error {{different template parameters}}
62   using err3 = tT0<short, t0>; // expected-error {{different template parameters}}
63 
64   using ok2 = Tt0<t0>;
65   using err4 = Tt0<it>; // expected-error {{different template parameters}}
66 }
67 
68 namespace Auto {
69   template<template<int> typename T> struct TInt {};
70   template<template<int*> typename T> struct TIntPtr {};
71   template<template<auto> typename T> struct TAuto {};
72   template<template<auto*> typename T> struct TAutoPtr {};
73   template<template<decltype(auto)> typename T> struct TDecltypeAuto {};
74   template<auto> struct Auto;
75   template<auto*> struct AutoPtr;
76   template<decltype(auto)> struct DecltypeAuto;
77   template<int> struct Int;
78   template<int*> struct IntPtr;
79 
80   TInt<Auto> ia;
81   TInt<AutoPtr> iap; // FIXME: ill-formed (?)
82   TInt<DecltypeAuto> ida;
83   TInt<Int> ii;
84   TInt<IntPtr> iip; // expected-error {{different template parameters}}
85 
86   TIntPtr<Auto> ipa;
87   TIntPtr<AutoPtr> ipap;
88   TIntPtr<DecltypeAuto> ipda;
89   TIntPtr<Int> ipi; // expected-error {{different template parameters}}
90   TIntPtr<IntPtr> ipip;
91 
92   TAuto<Auto> aa;
93   TAuto<AutoPtr> aap; // FIXME: ill-formed (?)
94   TAuto<Int> ai; // FIXME: ill-formed (?)
95   TAuto<IntPtr> aip; // FIXME: ill-formed (?)
96 
97   TAutoPtr<Auto> apa;
98   TAutoPtr<AutoPtr> apap;
99   TAutoPtr<Int> api; // FIXME: ill-formed (?)
100   TAutoPtr<IntPtr> apip; // FIXME: ill-formed (?)
101 
102   TDecltypeAuto<DecltypeAuto> dada;
103   TDecltypeAuto<Int> dai; // FIXME: ill-formed (?)
104   TDecltypeAuto<IntPtr> daip; // FIXME: ill-formed (?)
105 
106   // FIXME: It's completely unclear what should happen here, but these results
107   // seem at least plausible:
108   TAuto<DecltypeAuto> ada;
109   TAutoPtr<DecltypeAuto> apda;
110   // Perhaps this case should be invalid, as there are valid 'decltype(auto)'
111   // parameters (such as 'user-defined-type &') that are not valid 'auto'
112   // parameters.
113   TDecltypeAuto<Auto> daa;
114   TDecltypeAuto<AutoPtr> daap; // FIXME: should probably be ill-formed
115 
116   int n;
117   template<auto A, decltype(A) B = &n> struct SubstFailure;
118   TInt<SubstFailure> isf; // FIXME: this should be ill-formed
119   TIntPtr<SubstFailure> ipsf;
120 }
121