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 | |