1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s 2 3 // expected-note@temp_arg_template_p0522.cpp:* 1+{{template is declared here}} 4 // expected-note@temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}} 5 // expected-note@temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}} 6 7 template<template<int> typename> struct Ti; // #Ti 8 template<template<int...> typename> struct TPi; // #TPi 9 template<template<int, int...> typename> struct TiPi; 10 template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed? 11 12 template<typename T, template<T> typename> struct tT0; // #tT0 13 template<template<typename T, T> typename> struct Tt0; // #Tt0 14 15 template<template<typename> typename> struct Tt; 16 template<template<typename, typename...> typename> struct TtPt; 17 18 template<int> struct i; 19 template<int, int = 0> struct iDi; 20 template<int, int> struct ii; 21 template<int...> struct Pi; 22 template<int, int, int...> struct iiPi; 23 24 template<int, typename = int> struct iDt; // #iDt 25 template<int, typename> struct it; // #it 26 27 template<typename T, T v> struct t0; 28 29 template<typename...> struct Pt; 30 31 namespace IntParam { 32 using ok = Pt<Ti<i>, 33 Ti<iDi>, 34 Ti<Pi>, 35 Ti<iDt>>; 36 using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}} 37 // expected-note@-1 {{different template parameters}} 38 using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}} 39 // expected-note@-1 {{different template parameters}} 40 using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}} 41 // expected-note@-1 {{different template parameters}} 42 using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}} 43 // expected-note@-1 {{different template parameters}} 44 } 45 46 // These are accepted by the backwards-compatibility "parameter pack in 47 // parameter matches any number of parameters in arguments" rule. 48 namespace IntPackParam { 49 using ok = TPi<Pi>; 50 using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>; 51 using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}} 52 // expected-note@-1 {{different template parameters}} 53 using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}} 54 // expected-note@-1 {{different template parameters}} 55 using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}} 56 // expected-note@-1 {{different template parameters}} 57 } 58 59 namespace IntAndPackParam { 60 using ok = TiPi<Pi>; 61 using ok_compat = Pt<TiPi<ii>, TiPi<iDi>, TiPi<iiPi>>; 62 using err = TiPi<iDi>; 63 } 64 65 namespace DependentType { 66 using ok = Pt<tT0<int, i>, tT0<int, iDi>>; 67 using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}} 68 // expected-note@-1 {{different template parameters}} 69 using err2 = tT0<short, i>; 70 using err2a = tT0<long long, i>; // expected-error@#tT0 {{cannot be narrowed from type 'long long' to 'int'}} 71 // expected-note@-1 {{different template parameters}} 72 using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}} 73 // expected-note@-1 {{different template parameters}} 74 using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}} 75 // expected-note@-1 {{different template parameters}} 76 77 using ok2 = Tt0<t0>; 78 using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}} 79 // expected-note@-1 {{different template parameters}} 80 } 81 82 namespace Auto { 83 template<template<int> typename T> struct TInt {}; // #TInt 84 template<template<int*> typename T> struct TIntPtr {}; // #TIntPtr 85 template<template<auto> typename T> struct TAuto {}; 86 template<template<auto*> typename T> struct TAutoPtr {}; 87 template<template<decltype(auto)> typename T> struct TDecltypeAuto {}; 88 template<auto> struct Auto; 89 template<auto*> struct AutoPtr; // #AutoPtr 90 template<decltype(auto)> struct DecltypeAuto; 91 template<int> struct Int; 92 template<int*> struct IntPtr; 93 94 TInt<Auto> ia; 95 TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}} 96 // expected-note@-1 {{different template parameters}} 97 TInt<DecltypeAuto> ida; 98 TInt<Int> ii; 99 TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}} 100 // expected-note@-1 {{different template parameters}} 101 102 TIntPtr<Auto> ipa; 103 TIntPtr<AutoPtr> ipap; 104 TIntPtr<DecltypeAuto> ipda; 105 TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}} 106 // expected-note@-1 {{different template parameters}} 107 TIntPtr<IntPtr> ipip; 108 109 TAuto<Auto> aa; 110 TAuto<AutoPtr> aap; // expected-error@#AutoPtr {{could not match 'auto *' against 'auto'}} 111 // expected-note@-1 {{different template parameters}} 112 TAuto<Int> ai; // FIXME: ill-formed (?) 113 TAuto<IntPtr> aip; // FIXME: ill-formed (?) 114 115 TAutoPtr<Auto> apa; 116 TAutoPtr<AutoPtr> apap; 117 TAutoPtr<Int> api; // FIXME: ill-formed (?) 118 TAutoPtr<IntPtr> apip; // FIXME: ill-formed (?) 119 120 TDecltypeAuto<DecltypeAuto> dada; 121 TDecltypeAuto<Int> dai; // FIXME: ill-formed (?) 122 TDecltypeAuto<IntPtr> daip; // FIXME: ill-formed (?) 123 124 // FIXME: It's completely unclear what should happen here, but these results 125 // seem at least plausible: 126 TAuto<DecltypeAuto> ada; 127 TAutoPtr<DecltypeAuto> apda; 128 // Perhaps this case should be invalid, as there are valid 'decltype(auto)' 129 // parameters (such as 'user-defined-type &') that are not valid 'auto' 130 // parameters. 131 TDecltypeAuto<Auto> daa; 132 TDecltypeAuto<AutoPtr> daap; // expected-error@#AutoPtr {{could not match 'auto *' against 'decltype(auto)'}} 133 // expected-note@-1 {{different template parameters}} 134 135 int n; 136 template<auto A, decltype(A) B = &n> struct SubstFailure; 137 TInt<SubstFailure> isf; // FIXME: this should be ill-formed 138 TIntPtr<SubstFailure> ipsf; 139 } 140 141 namespace GH62529 { 142 // Note: the constraint here is just for bypassing a fast-path. 143 template<class T1> requires(true) using A = int; 144 template<template<class ...T2s> class TT1, class T3> struct B {}; 145 template<class T4> B<A, T4> f(); 146 auto t = f<int>(); 147 } // namespace GH62529 148 149 namespace GH101394 { 150 struct X {}; // #X 151 struct Y { 152 constexpr Y(const X &) {} 153 }; 154 155 namespace t1 { 156 template<template<X> class> struct A {}; 157 template<Y> struct B; 158 template struct A<B>; 159 } // namespace t1 160 namespace t2 { 161 template<template<Y> class> struct A {}; // #A 162 template<X> struct B; // #B 163 template struct A<B>; 164 // expected-error@#A {{no viable conversion from 'const Y' to 'X'}} 165 // expected-note@-2 {{different template parameters}} 166 // expected-note@#X 2{{not viable}} 167 // expected-note@#B {{passing argument to parameter here}} 168 } // namespace t2 169 } // namespace GH101394 170