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